- DDS Function Generator คืออะไร?
- ทำความเข้าใจการทำงานของ IC Generator ฟังก์ชัน AD9833
- ส่วนประกอบที่จำเป็นในการสร้างฟังก์ชัน Generator ตาม AD9833
- AD9833 ตามฟังก์ชัน Generator - แผนผัง
- AD9833 ตามฟังก์ชัน Generator - รหัส Arduino
- ทดสอบตัวสร้างฟังก์ชันที่ใช้ AD9833
- การปรับปรุงเพิ่มเติม
หากคุณเป็นผู้ที่ชื่นชอบอิเล็กทรอนิกส์เช่นฉันที่ต้องการปรับแต่งวงจรอิเล็กทรอนิกส์ที่แตกต่างกันการมีFunction Generator ที่ดีบางครั้งก็กลายเป็นข้อบังคับ แต่การเป็นเจ้าของเครื่องหนึ่งเป็นปัญหาเพราะอุปกรณ์พื้นฐานดังกล่าวอาจทำให้เสียเงินได้ การสร้างอุปกรณ์ทดสอบของคุณเองไม่เพียง แต่ถูกกว่า แต่ยังเป็นวิธีที่ดีในการพัฒนาความรู้ของคุณอีกด้วย
ดังนั้นในบทความนี้เราจะสร้างSignal Generator อย่างง่ายด้วย Arduino และ AD9833 DDS Function Generator Moduleซึ่งสามารถสร้างคลื่นไซน์สี่เหลี่ยมและสามเหลี่ยมที่มีความถี่สูงสุด 12 MHz ที่เอาต์พุต และในที่สุดเราจะทดสอบความถี่เอาต์พุตโดยใช้ออสซิลโลสโคปของเรา
ก่อนหน้านี้เราได้สร้าง Simple Sine Wave Generator, Square Wave Generator และ Triangle Wave Generator ด้วยความช่วยเหลือของวงจรอะนาล็อกพื้นฐาน คุณสามารถตรวจสอบสิ่งเหล่านี้ได้หากคุณกำลังมองหาวงจรกำเนิดสัญญาณรูปคลื่นพื้นฐาน นอกจากนี้หากคุณต้องการสร้างเครื่องกำเนิดฟังก์ชัน Arduino ที่ถูกกว่าโดยไม่ต้องใช้โมดูล AD9833 คุณสามารถตรวจสอบโครงการ DIY Arduino Waveform Generator
DDS Function Generator คืออะไร?
ตามความหมายของชื่อเครื่องกำเนิดฟังก์ชันคืออุปกรณ์ที่สามารถส่งออกรูปคลื่นเฉพาะที่มีความถี่เฉพาะตามการตั้งค่า ตัวอย่างเช่นพิจารณาว่าคุณมีตัวกรอง LC ที่คุณต้องการทดสอบการตอบสนองความถี่เอาท์พุทของคุณคุณสามารถทำได้อย่างง่ายดายโดยใช้ตัวสร้างฟังก์ชัน สิ่งที่คุณต้องทำคือตั้งค่าความถี่เอาต์พุตและรูปคลื่นที่คุณต้องการจากนั้นคุณสามารถหมุนลงหรือขึ้นเพื่อทดสอบการตอบสนอง นี่เป็นเพียงตัวอย่างเดียวคุณสามารถทำสิ่งต่างๆได้มากขึ้นเมื่อรายการดำเนินต่อไป
ท.บ. ย่อมาจากการสังเคราะห์สารดิจิตอลโดยตรงเป็นเครื่องกำเนิดรูปคลื่นชนิดหนึ่งที่ใช้ตัวแปลงดิจิตอลเป็นอนาล็อก (DAC) เพื่อสร้างสัญญาณจากพื้นดินขึ้น วิธีนี้ใช้เพื่อสร้างคลื่นไซน์โดยเฉพาะ แต่ IC ที่เราใช้สามารถผลิตสัญญาณคลื่นสี่เหลี่ยมหรือสามเหลี่ยม การทำงานที่เกิดขึ้นภายในชิป DDS เป็นแบบดิจิทัลจึงสามารถเปลี่ยนความถี่ได้เร็วมากหรือสามารถเปลี่ยนจากสัญญาณหนึ่งไปยังอีกสัญญาณหนึ่งได้อย่างรวดเร็ว อุปกรณ์นี้มีความละเอียดความถี่ละเอียดพร้อมสเปกตรัมความถี่กว้าง
ทำความเข้าใจการทำงานของ IC Generator ฟังก์ชัน AD9833
หัวใจสำคัญของโครงการคือAD9833 Programmable Waveform Generator IC ซึ่งออกแบบและพัฒนาโดยอุปกรณ์อนาล็อก มันเป็นพลังงานต่ำกำเนิดสัญญาณที่ตั้งโปรแกรมที่มีความสามารถในการผลิตไซน์, สามเหลี่ยมและตารางคลื่นที่มีความถี่สูงสุด 12 MHz เป็น IC ที่ไม่เหมือนใครซึ่งสามารถปรับเปลี่ยนความถี่และเฟสเอาต์พุตได้ด้วยโปรแกรมซอฟต์แวร์ มีอินเทอร์เฟซ SPI 3 สายซึ่งเป็นเหตุผลว่าทำไมการสื่อสารกับ IC นี้จึงกลายเป็นเรื่องง่ายและสะดวก แผนภาพบล็อกการทำงานของ IC นี้แสดงอยู่ด้านล่าง
การทำงานของ IC นี้ง่ายมาก หากเราดูที่แผนภาพบล็อกการทำงานด้านบนเราจะสังเกตได้ว่าเรามี Phase Accumulator ซึ่งมีหน้าที่เก็บค่าดิจิตอลทั้งหมดที่เป็นไปได้ของคลื่นไซน์โดยเริ่มจาก 0 ถึง2π ต่อไปเรามี SIN ROM ซึ่งมีหน้าที่ในการแปลงข้อมูลเฟสที่สามารถแมปโดยตรงเป็นแอมพลิจูดได้ SIN ROM ใช้ข้อมูลเฟสดิจิทัลเป็นที่อยู่ในตารางการค้นหาและแปลงข้อมูลเฟสเป็นแอมพลิจูด และสุดท้ายเรามีตัวแปลงดิจิตอลเป็นอนาล็อก 10 บิตซึ่งมีหน้าที่รับข้อมูลดิจิทัลจาก SIN ROM และแปลงเป็นแรงดันไฟฟ้าอะนาล็อกที่สอดคล้องกันนั่นคือสิ่งที่เราได้รับจากเอาต์พุต ที่เอาต์พุตเรายังมีสวิตช์ที่เราสามารถเปิดหรือปิดได้ด้วยรหัสซอฟต์แวร์เพียงเล็กน้อย เราจะพูดถึงเรื่องนี้ในบทความต่อไปรายละเอียดที่คุณเห็นด้านบนเป็นเวอร์ชันที่ถูกถอดออกอย่างมากเกี่ยวกับสิ่งที่เกิดขึ้นภายใน IC และรายละเอียดส่วนใหญ่ที่คุณเห็นด้านบนนำมาจากแผ่นข้อมูล AD9833 คุณสามารถตรวจสอบข้อมูลเพิ่มเติมได้
ส่วนประกอบที่จำเป็นในการสร้างฟังก์ชัน Generator ตาม AD9833
ส่วนประกอบที่จำเป็นในการสร้างเครื่องกำเนิดฟังก์ชันที่ใช้ AD9833 แสดงอยู่ด้านล่างเราออกแบบวงจรนี้ด้วยส่วนประกอบทั่วไปซึ่งทำให้กระบวนการจำลองแบบง่ายมาก
- Arduino นาโน - 1
- AD9833 DDS Function Generator - 1
- จอแสดงผล OLED 128 X 64 - 1
- เครื่องเข้ารหัสโรตารีทั่วไป - 1
- แจ็ค Barrel DC - 1
- LM7809 ตัวควบคุมแรงดันไฟฟ้า - 1
- ตัวเก็บประจุ 470uF - 1
- ตัวเก็บประจุ 220uF - 1
- 104pF ตัวเก็บประจุ - 1
- ตัวต้านทาน 10K - 6
- สวิตช์สัมผัส - 4
- ขั้วต่อสกรู 5.04 มม. - 1
- ส่วนหัวหญิง - 1
- แหล่งจ่ายไฟ 12V - 1
AD9833 ตามฟังก์ชัน Generator - แผนผัง
แผนภาพวงจรที่สมบูรณ์สำหรับAD9833 และ Arduino Based Function Generatorแสดงไว้ด้านล่าง
เราจะใช้AD9833 กับ Arduinoเพื่อสร้างความถี่ที่เราต้องการ และในส่วนนี้เราจะอธิบายรายละเอียดทั้งหมดด้วยความช่วยเหลือของแผนผัง ให้ฉันอธิบายภาพรวมคร่าวๆของสิ่งที่เกิดขึ้นกับวงจร เริ่มต้นด้วยโมดูล AD9833. โมดูล AD9833 เป็นโมดูลกำเนิดฟังก์ชันและเชื่อมต่อกับ Arduino ตามแผนผัง ในการจ่ายไฟให้กับวงจรเราใช้ IC ควบคุมแรงดันไฟฟ้า LM7809 พร้อมตัวเก็บประจุแบบแยกส่วนที่เหมาะสมซึ่งเป็นสิ่งจำเป็นเนื่องจากสัญญาณรบกวนของแหล่งจ่ายสามารถรบกวนสัญญาณเอาต์พุตซึ่งส่งผลให้เอาต์พุตที่ไม่ต้องการ เช่นเคย Arduino ทำงานเป็นสมองสำหรับโครงการนี้ เพื่อแสดงความถี่ที่ตั้งไว้และข้อมูลที่มีค่าอื่น ๆ เราได้เชื่อมต่อโมดูลจอแสดงผล 128 X 64 OLED ในการเปลี่ยนช่วงความถี่เรากำลังใช้สวิตช์สามตัว อันแรกตั้งค่าความถี่เป็น Hz อันที่สองตั้งความถี่เอาท์พุทเป็น KHz และอันที่สามกำหนดความถี่เป็น MHz เรายังมีปุ่มอื่นที่สามารถใช้เพื่อเปิดหรือปิดเอาต์พุตได้ ในที่สุดเราก็มีตัวเข้ารหัสแบบหมุนและเราต้องแนบตัวต้านทานแบบดึงขึ้นด้วยมิฉะนั้นสวิตช์เหล่านี้จะไม่ทำงานเนื่องจากเรากำลังตรวจสอบเหตุการณ์การกดปุ่มบนวิธีการรวม ตัวเข้ารหัสแบบหมุนใช้เพื่อเปลี่ยนความถี่และใช้สวิตช์สัมผัสภายในตัวเข้ารหัสแบบหมุนเพื่อเลือกรูปคลื่นที่ตั้งไว้
AD9833 ตามฟังก์ชัน Generator - รหัส Arduino
คุณสามารถดูรหัสทั้งหมดที่ใช้ในโครงการนี้ได้ที่ด้านล่างของหน้านี้ หลังจากเพิ่มไฟล์ส่วนหัวและไฟล์ต้นฉบับที่ต้องการแล้วคุณควรจะสามารถคอมไพล์ไฟล์ Arduino ได้โดยตรง คุณสามารถดาวน์โหลดไลบรารี ad9833 Arduinoและไลบรารีอื่น ๆ ได้จากลิงค์ด้านล่างหรือมิฉะนั้นคุณสามารถใช้วิธีการจัดการบอร์ดเพื่อติดตั้งไลบรารี
- ดาวน์โหลด AD9833 Library โดย Bill Williams
- ดาวน์โหลด SSD1306 OLED Library โดย Adafruit
- ดาวน์โหลด Adafruit GFX library
คำอธิบายของรหัสใน ino ไฟล์ มีดังนี้ อันดับแรกเราเริ่มต้นด้วยการรวมไลบรารีที่จำเป็นทั้งหมด ไลบรารีสำหรับโมดูล AD9833 DDSตามด้วยไลบรารีสำหรับ OLED ก่อนและไลบรารีคณิตศาสตร์เป็นสิ่งจำเป็นสำหรับการคำนวณของเรา
#include // LIbrary for AD9833 Module #include
ต่อไปเราจะกำหนดพินอินพุตและเอาต์พุตที่จำเป็นทั้งหมดสำหรับปุ่มสวิตช์ตัวเข้ารหัสแบบหมุนและ OLED
# กำหนด SCREEN_WIDATA_PINH 128 // ความกว้างของจอแสดงผล OLED เป็นพิกเซล #define SCREEN_HEIGHT 64 // ความสูงของจอแสดงผล OLED เป็นพิกเซล # กำหนด SET_FREQUENCY_HZ A2 // ปุ่มกดเพื่อตั้งค่าความถี่ใน Hz #define SET_FREQUENCY_KHZ A3 // ปุ่มกดเพื่อตั้งค่าความถี่ในหน่วย Khz #define A6 // ปุ่มกดเพื่อตั้งค่าความถี่ใน Mhz # กำหนด ENABLE_DISABLE_OUTPUT_PIN A7 // ปุ่มกดเพื่อเปิด / ปิดการใช้งานเอาต์พุต #define FNC_PIN 4 // Fsync ที่ต้องการโดยโมดูล AD9833 # กำหนด CLK_PIN 8 // เข็มนาฬิกาของตัวเข้ารหัส # กำหนด DATA_PIN 7 / / Data Pin ของ Encoder #define BTN_PIN 9 // ปุ่มกดภายในบนตัวเข้ารหัส
หลังจากนั้นเรากำหนดตัวแปรที่จำเป็นทั้งหมดที่จำเป็นในรหัสนี้ ขั้นแรกเรากำหนดตัวนับตัวแปรจำนวนเต็มซึ่งจะเก็บค่าตัวเข้ารหัสแบบหมุน ตัวแปรสองตัวถัดไปclockPinและclockPinStateเก็บรูปปั้นพินที่จำเป็นในการทำความเข้าใจทิศทางตัวเข้ารหัส เรามีตัวแปรเวลาที่เก็บค่าตัวจับเวลาปัจจุบันตัวแปรนี้ใช้สำหรับการดีบักปุ่ม ต่อไปเรามีโมดูลตัวแปรยาวที่ไม่ได้ลงชื่อซึ่งเก็บความถี่ที่คำนวณได้ซึ่งจะถูกนำไปใช้ ต่อไปเราจะมีความล่าช้า debounceความล่าช้านี้สามารถปรับเปลี่ยนได้ตามต้องการ ต่อไปเรามีสามตัวแปรบูลset_frequency_hz,set_frequency_Khzและ set_frequency_Mhz ตัวแปรทั้งสามนี้ใช้เพื่อกำหนดการตั้งค่าปัจจุบันของโมดูล เราจะพูดถึงรายละเอียดเพิ่มเติมในบทความต่อไป ต่อไปเรามีตัวแปรที่เก็บสถานะของรูปคลื่นเอาต์พุตรูปคลื่นเอาต์พุตเริ่มต้นคือคลื่นไซน์ และสุดท้ายเรามีตัวแปรencoder_btn_countที่เก็บจำนวนปุ่มตัวเข้ารหัสซึ่งใช้ในการตั้งค่ารูปคลื่นเอาต์พุต
ตัวนับ int = 1; // ค่าตัวนับนี้จะเพิ่มขึ้นหรือลดลงถ้าเมื่อตัวเข้ารหัสแบบหมุนเปลี่ยนเป็น int clockPin; // ตัวยึดสำหรับสถานะพินที่ใช้โดย clockPinState ตัวเข้ารหัสแบบหมุน // ตัวยึดสำหรับสถานะพินที่ใช้โดยตัวเข้ารหัสแบบหมุนที่ไม่ได้ลงชื่อเป็นเวลานาน = 0; // ใช้สำหรับ debouncing moduleFrequency ยาวที่ไม่ได้ลงชื่อ; // ใช้เพื่อตั้งค่าความถี่เอาต์พุต long debounce = 220; // ดีเลย์การดีเลย์บูล btn_state; // ใช้เพื่อปิดการใช้งานเอาต์พุตของ AD98333 Module bool set_frequency_hz = 1; // ความถี่เริ่มต้นของบูลโมดูล AD9833 set_frequency_khz; บูล set_frequency_mhz; สตริง waveSelect = "SIN"; // รูปคลื่นเริ่มต้นของโมดูล int encoder_btn_count = 0; // ใช้เพื่อตรวจสอบปุ่มตัวเข้ารหัสกดถัดไปเรามีวัตถุสองชิ้นของเราหนึ่งชิ้นสำหรับจอแสดงผล OLED และอีกชิ้นหนึ่งสำหรับโมดูล AD9833จอแสดงผล Adafruit_SSD1306 (SCREEN_WIDATA_PINH, SCREEN_HEIGHT, & Wire, -1); รุ่น AD9833 (FNC_PIN);
ต่อไปเรามีฟังก์ชั่นการตั้งค่า ()ของเราในฟังก์ชั่นการตั้งค่านั้นเราเริ่มต้นด้วยการเปิดใช้งาน Serial สำหรับการดีบัก เราเริ่มต้นโมดูล AD9833 ด้วยความช่วยเหลือของเริ่มต้น ()วิธีการ ต่อไปเราตั้งค่าพินเข้ารหัสแบบหมุนที่กำหนดทั้งหมดเป็นอินพุต และเราเก็บค่าของเข็มนาฬิกาไว้ในตัวแปรclockPinStateนี่เป็นขั้นตอนที่จำเป็นสำหรับตัวเข้ารหัสแบบหมุน
ต่อไปเราจะตั้งค่าทั้งหมดหมุดปุ่มเป็น input และเปิดใช้งานจอแสดงผล OLED ด้วยความช่วยเหลือของ display.begin () วิธีการและเรายังตรวจสอบข้อผิดพลาดใด ๆ ที่มีคำว่าเมื่อเสร็จแล้วเราจะล้างการแสดงผลและพิมพ์หน้าจอเริ่มต้นเริ่มต้นเราเพิ่มการหน่วงเวลา 2 วินาทีซึ่งเป็นความล่าช้าสำหรับหน้าจอเริ่มต้นและสุดท้ายเราเรียกฟังก์ชัน update_display ()ซึ่งจะล้างหน้าจอและอัปเดต แสดงอีกครั้ง รายละเอียดของวิธี update_display () จะกล่าวถึงต่อไปในบทความ
การตั้งค่าเป็นโมฆะ () {Serial.begin (9600); // เปิดใช้งาน Serial @ 9600 baud genBegin (); // นี่ต้องเป็นคำสั่งแรกหลังจากประกาศ pinMode วัตถุ AD9833 (CLK_PIN, INPUT); // การตั้งค่าพินเป็น pinMode อินพุต (DATA_PIN, INPUT); pinMode (BTN_PIN, INPUT_PULLUP); clockPinState = digitalRead (CLK_PIN); pinMode (SET_FREQUENCY_HZ, INPUT); // การตั้งค่าพินเป็นโหมดพินอินพุต (SET_FREQUENCY_KHZ, INPUT); pinMode (SET_FREQUENCY_MHZ, INPUT); pinMode (ENABLE_DISABLE_OUTPUT_PIN, INPUT); if (! display.begin (SSD1306_SWITCHCAPVCC, 0x3C)) {// แอดเดรส 0x3D สำหรับ 128x64 Serial.println (F ("การจัดสรร SSD1306 ล้มเหลว")); สำหรับ (;;); } display.clearDisplay (); // ล้างหน้าจอ display.setTextSize (2); // กำหนดขนาดข้อความ display.setTextColor (WHITE); // ตั้งค่า LCD Color display.setCursor (30, 0); // ตั้งค่าตำแหน่งเคอร์เซอร์ display.println ("AD9833"); // พิมพ์การแสดงข้อความนี้setCursor (17, 20); // ตั้งค่าตำแหน่งเคอร์เซอร์ display.println ("Function"); // พิมพ์ข้อความนี้ display.setCursor (13, 40); // ตั้งค่าตำแหน่งเคอร์เซอร์ display.println ("Generator"); // พิมพ์ข้อความนี้ display.display (); // อัปเดตความล่าช้าในการแสดงผล (2000); // ความล่าช้า 2 SEC update_display (); // เรียกใช้ update_display Function}
ต่อไปเรามีฟังก์ชันloop ()ของเราฟังก์ชันหลักทั้งหมดจะถูกเขียนไว้ในส่วนลูป
ขั้นแรกเราอ่านขานาฬิกาของตัวเข้ารหัสแบบหมุนและเก็บไว้ในตัวแปร clockPin ที่เราได้ประกาศไว้ก่อนหน้านี้ ต่อไปในคำสั่ง if เราจะตรวจสอบว่าค่าก่อนหน้าของพินและค่าปัจจุบันของพินนั้นใกล้เคียงกันหรือไม่และตรวจสอบค่าปัจจุบันของพินด้วย หากเป็นจริงทั้งหมดเราจะตรวจสอบพินข้อมูลหากเป็นจริงนั่นหมายความว่าตัวเข้ารหัสกำลังหมุนทวนเข็มนาฬิกาและเราลดค่าตัวนับด้วยความช่วยเหลือของคำสั่งcounter - มิฉะนั้นเราจะเพิ่มค่าตัวนับด้วยคำสั่งcounter ++ สุดท้ายเราใส่คำสั่ง if อื่นเพื่อตั้งค่าต่ำสุดเป็น 1 ต่อไปเราจะอัปเดตclockPinStateด้วยclockPinปัจจุบันคุ้มค่าสำหรับการใช้งานในอนาคต
โมฆะ loop () {clockPin = digitalRead (CLK_PIN); ถ้า (clockPin! = clockPinState && clockPin == 1) {if (digitalRead (DATA_PIN)! = clockPin) {ตัวนับ -; } else {ตัวนับ ++; // ตัวเข้ารหัสกำลังหมุน CW ดังนั้นเพิ่มขึ้น} ถ้า (ตัวนับ <1) ตัวนับ = 1; Serial.println (ตัวนับ); update_display (); }
ต่อไปเรามีรหัสของเราเพื่อตรวจจับการกดปุ่ม ในส่วนนี้เราได้ตรวจพบปุ่มภายในตัวเข้ารหัสด้วยความช่วยเหลือของคำสั่ง if ที่ซ้อนกันบางคำสั่งif (digitalRead (BTN_PIN) == LOW && millis () - เวลา> บอกเลิก) ในคำสั่งนี้ก่อนอื่นเราตรวจสอบว่าปุ่ม พินต่ำหรือไม่ถ้าต่ำแสดงว่าถูกกด จากนั้นเราตรวจสอบค่าตัวจับเวลาอีกครั้งด้วยการหน่วงเวลา debounce หากทั้งสองข้อความเป็นจริงเราจะประกาศว่าเป็นการดำเนินการกดปุ่มสำเร็จถ้าเราเพิ่มค่าencoder_btn_countต่อไปเราจะประกาศอีกคำสั่ง if เพื่อตั้งค่าตัวนับสูงสุดเป็น 2 เราต้องการมันเพราะเราใช้มันเพื่อตั้งค่ารูปคลื่นเอาท์พุตคำสั่ง if สามรายการที่ต่อเนื่องกันทำเช่นนั้นถ้าค่าเป็นศูนย์จะเลือกรูปคลื่นไซน์ถ้าเป็นหนึ่งรูปคลื่นจะเป็นรูปคลื่นสี่เหลี่ยมและถ้าค่าเป็น 2 จะเป็นคลื่นสามเหลี่ยม ในทั้งสามเหล่านี้ถ้างบเราปรับปรุงการแสดงผลที่มี update_display () ฟังก์ชั่น และสุดท้ายเราจะอัปเดตตัวแปรเวลาด้วยค่าตัวนับตัวจับเวลาปัจจุบัน
// หากเราตรวจพบสัญญาณ LOW ปุ่มจะถูกกด if (digitalRead (BTN_PIN) == LOW && millis () - time> debounce) {encoder_btn_count ++; // เพิ่มค่าถ้า (encoder_btn_count> 2) // ถ้าค่ามากกว่า 2 ให้รีเซ็ตเป็น 0 {encoder_btn_count = 0; } if (encoder_btn_count == 0) {// ถ้าค่าเป็น 0 คลื่นไซน์ถูกเลือก waveSelect = "SIN"; // อัปเดตตัวแปรสตริงด้วยค่า sin update_display (); // อัปเดตการแสดงผล} if (encoder_btn_count == 1) {// ถ้าค่าเป็น 1 คลื่นสี่เหลี่ยมถูกเลือก waveSelect = "SQR"; // อัปเดตตัวแปรสตริงด้วยค่า SQR update_display (); // อัปเดตการแสดงผล} if (encoder_btn_count == 2) {// ถ้าค่าเป็น 1 คลื่นสามเหลี่ยมจะถูกเลือก waveSelect = "TRI"; // อัปเดตตัวแปรสตริงด้วยค่า TRI update_display ();// ปรับปรุงการแสดงผล} time = millis (); // อัปเดตตัวแปรเวลา}
ต่อไปเราจะกำหนดรหัสที่จำเป็นทั้งหมดที่จำเป็นในการตั้งค่าปุ่มทั้งหมดด้วยการหน่วงเวลา debounce เนื่องจากปุ่มต่างๆเชื่อมต่อกับพินอะนาล็อกของ Arduino เราจึงใช้คำสั่งอ่านแบบอะนาล็อกเพื่อระบุการกดปุ่มหากค่าการอ่านแบบอะนาล็อกถึงต่ำกว่า 30 จากนั้นเราจะตรวจพบการกดปุ่มสำเร็จและเรารอ 200 ms ถึง ตรวจสอบว่าเป็นการกดปุ่มจริงหรือเสียงเท่านั้น หากคำสั่งนี้เป็นจริงเราจะกำหนดตัวแปรบูลีนด้วยค่าที่ใช้ในการตั้งค่า Hz, Khz และ Mhz ของตัวสร้างฟังก์ชัน ต่อไปเราจะอัปเดตการแสดงผลและอัปเดตตัวแปรเวลา เราทำเช่นนั้นสำหรับปุ่มทั้งสี่ที่เชื่อมต่อกับ Arduino
ถ้า (analogRead (SET_FREQUENCY_HZ) <30 && millis () - เวลา> debounce) {set_frequency_hz = 1; // อัปเดตค่าบูลีน set_frequency_khz = 0; set_frequency_mhz = 0; update_display (); // update the display time = millis (); // update the time variable} if (analogRead (SET_FREQUENCY_KHZ) <30 && millis () - time> debounce) {set_frequency_hz = 0; // อัปเดตค่าบูลีน set_frequency_khz = 1; set_frequency_mhz = 0; moduleFrequency = ตัวนับ * 1,000; update_display (); // อัปเดตเวลาแสดงผล = มิลลิวินาที (); // อัปเดตตัวแปรเวลา} if (analogRead (SET_FREQUENCY_MHZ) <30 && millis () - เวลา> debounce) {// ตรวจสอบพินอนาล็อกด้วยการหน่วงเวลา debounce set_frequency_hz = 0; // อัปเดตค่าบูลีน set_frequency_khz = 0; set_frequency_mhz = 1; moduleFrequency = ตัวนับ * 1000000; update_display ();// อัปเดตเวลาแสดงผล = มิลลิวินาที (); // อัปเดตตัวแปรเวลา} if (analogRead (ENABLE_DISABLE_OUTPUT_PIN) <30 && millis () - time> debounce) {// ตรวจสอบพินอนาล็อกด้วยการหน่วงเวลา debounce btn_state =! btn_state; // สลับสถานะปุ่ม gen.EnableOutput (btn_state); // เปิด / ปิดการใช้งานเอาต์พุตของตัวสร้างฟังก์ชันขึ้นอยู่กับสถานะปุ่ม update_display (); // อัปเดตเวลาแสดงผล = มิลลิวินาที (); // อัปเดตตัวแปรเวลา}}// อัปเดตตัวแปรเวลา}}// อัปเดตตัวแปรเวลา}}
สุดท้ายเรามีของเราupdate_display ()ฟังก์ชั่น ในฟังก์ชั่นนี้เราทำได้มากกว่าการอัปเดตจอแสดงผลนี้เนื่องจากบางส่วนของหน้าจอไม่สามารถอัปเดตใน OLED ในการอัปเดตคุณต้องทาสีใหม่ด้วยค่าใหม่ ทำให้กระบวนการเข้ารหัสยากขึ้นมาก
ภายในฟังก์ชั่นนี้เราเริ่มต้นด้วยการล้างการแสดงผล ต่อไปเรากำหนดขนาดตัวอักษรที่ต้องการ หลังจากนั้นเราตั้งค่าเคอร์เซอร์และพิมพ์ฟังก์ชัน Generator ด้วยdisplay.println ("ฟังก์ชันฟังก์ชัน"); คำสั่ง เราตั้งค่าขนาดตัวอักษรเป็น 2 อีกครั้งและเคอร์เซอร์เป็น (0,20) ด้วยความช่วยเหลือของ ฟังก์ชัน display.setCursor (0, 20)
นี่คือที่ที่เราพิมพ์ข้อมูลว่าคลื่นคืออะไร
display.clearDisplay (); // FIrst ล้างการแสดง display.setTextSize (1); // กำหนดขนาดข้อความ display.setCursor (10, 0); // ตั้งค่าตำแหน่งเคอร์เซอร์ display.println ("Function Generator"); // พิมพ์ข้อความ display.setTextSize (2); // กำหนดขนาดข้อความ display.setCursor (0, 20); // กำหนดตำแหน่งเคอร์เซอร์
ต่อไปเราจะตรวจสอบตัวแปรบูลีนสำหรับรายละเอียดความถี่และอัปเดตค่าในตัวแปรmoduleFrequency เราทำสิ่งนี้สำหรับค่า Hz, kHz และ MHz ต่อไปเราจะตรวจสอบตัวแปรwaveSelectและระบุว่าคลื่นใดถูกเลือก ตอนนี้เรามีค่าที่จะกำหนดประเภทคลื่นและความถี่
if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {// ตรวจสอบว่าปุ่มสำหรับตั้งค่าความถี่เป็น Hz ถูกกด moduleFrequency = counter; // อัปเดตตัวแปร moduleFrequency ด้วยค่าตัวนับปัจจุบัน} ถ้า (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {// ตรวจสอบว่าปุ่มสำหรับตั้งค่าความถี่ใน KHz ถูกกด moduleFrequency = counter * 1000; // อัปเดตตัวแปร moduleFrequency ด้วยค่าตัวนับปัจจุบัน แต่เราคูณ 1000 เพื่อตั้งค่าเป็น KHZ} ถ้า (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {// ตรวจสอบว่าปุ่มสำหรับการตั้งค่าความถี่ใน MHz ถูกกด moduleFrequency = ตัวนับ * 1000000; ถ้า (moduleFrequency> 12000000) {moduleFrequency = 12000000;// อย่าปล่อยให้ความถี่ถูกขูดว่า 12Mhz counter = 12; }} if (waveSelect == "SIN") {// Sine wave ถูกเลือก display.println ("SIN"); gen.ApplySignal (SINE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "SQR") {// Sqr wave ถูกเลือก display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri wave ถูกเลือก display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // อัปเดตโมดูล AD9833 Serial.println (moduleFrequency); }} if (waveSelect == "SQR") {// Sqr wave ถูกเลือก display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri wave ถูกเลือก display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // อัปเดตโมดูล AD9833 Serial.println (moduleFrequency); }} if (waveSelect == "SQR") {// Sqr wave ถูกเลือก display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri wave ถูกเลือก display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // อัปเดตโมดูล AD9833 Serial.println (moduleFrequency); }
เราตั้งค่าเคอร์เซอร์อีกครั้งและอัปเดตค่าตัวนับ เราตรวจสอบบูลีนอีกครั้งเพื่ออัปเดตช่วงความถี่บนจอแสดงผลเราต้องทำเช่นนี้เพราะหลักการทำงานของ OLED นั้นแปลกมาก
display.setCursor (45, 20); display.println (ตัวนับ); // พิมพ์ข้อมูลตัวนับบนจอแสดงผล ถ้า (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {display.setCursor (90, 20); display.println ("เฮิรตซ์"); // พิมพ์ Hz บนหน้าจอ display.display (); // เมื่อทุกชุดอัปเดตการแสดงผล} if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {display.setCursor (90, 20); display.println ("Khz"); display.display (); // เมื่อทุกชุดอัปเดตการแสดงผล} if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {display.setCursor (90, 20); display.println ("Mhz"); display.display (); // เมื่อทุกอย่างอัปเดตการแสดงผล}
ต่อไปเราจะตรวจสอบตัวแปรการกดปุ่มเพื่อพิมพ์เอาต์พุตเปิด / ปิดไปยัง OLED ต้องทำอีกครั้งเนื่องจากโมดูล OLED
ถ้า (btn_state) {display.setTextSize (1); display.setCursor (65, 45); display.print ("เปิดเอาต์พุต"); // พิมพ์เอาต์พุตไปยัง display.display (); display.setTextSize (2); } else {display.setTextSize (1); display.setCursor (65, 45); display.print ("เอาต์พุตปิด"); // พิมพ์เอาต์พุตออกไปยัง display.display (); display.setTextSize (2); }
นี่ถือเป็นการสิ้นสุดกระบวนการเข้ารหัสของเรา หากคุณสับสนในตอนนี้คุณสามารถตรวจสอบความคิดเห็นในโค้ดเพื่อทำความเข้าใจเพิ่มเติม
ทดสอบตัวสร้างฟังก์ชันที่ใช้ AD9833
ในการทดสอบวงจรจะใช้การตั้งค่าข้างต้น อย่างที่คุณเห็นเราได้เชื่อมต่ออะแดปเตอร์ไฟ 12V DC เข้ากับแจ็คบาร์เรล DC และเราได้เชื่อมต่อ Hantek Oscilloscope เข้ากับเอาต์พุตของวงจร เราได้เชื่อมต่อออสซิลโลสโคปเข้ากับแล็ปท็อปเพื่อแสดงภาพและวัดความถี่เอาต์พุต
เมื่อเสร็จแล้วเราตั้งค่าความถี่เอาต์พุตเป็น 5Khz ด้วยความช่วยเหลือของตัวเข้ารหัสแบบหมุนและเราทดสอบคลื่นไซน์เอาต์พุตและแน่นอนว่าเป็นคลื่นไซน์ 5Khz ที่เอาต์พุต
ต่อไปเราได้เปลี่ยนรูปคลื่นเอาท์พุตเป็นคลื่นสามเหลี่ยม แต่ความถี่ยังคงเหมือนเดิมรูปคลื่นเอาท์พุตดังแสดงด้านล่าง
จากนั้นเราเปลี่ยนเอาต์พุตเป็นคลื่นสี่เหลี่ยมและสังเกตผลลัพธ์และมันก็เป็นคลื่นสี่เหลี่ยมที่สมบูรณ์แบบ
นอกจากนี้เรายังปรับเปลี่ยนช่วงความถี่และทดสอบเอาต์พุตและทำงานได้ดี
การปรับปรุงเพิ่มเติม
วงจรนี้เป็นเพียงการพิสูจน์แนวคิดและต้องการการปรับปรุงเพิ่มเติม อันดับแรกเราต้องมี PCB คุณภาพดีและขั้วต่อ BNC คุณภาพดีสำหรับเอาต์พุตมิฉะนั้นเราจะไม่สามารถรับความถี่ที่สูงขึ้นได้ แอมพลิจูดของโมดูลนั้นต่ำมากดังนั้นเพื่อเพิ่มประสิทธิภาพเราจำเป็นต้องมีวงจร op-amp เพื่อขยายแรงดันไฟฟ้าขาออก สามารถเชื่อมต่อโพเทนชิออมิเตอร์เพื่อปรับความกว้างเอาต์พุตได้ สามารถเชื่อมต่อสวิตช์สำหรับชดเชยสัญญาณได้ นี่เป็นคุณสมบัติที่ต้องมี และยิ่งไปกว่านั้นโค้ดต้องได้รับการปรับปรุงอย่างมากเนื่องจากมีข้อบกพร่องเล็กน้อย สุดท้ายต้องเปลี่ยนจอแสดงผล OLED มิฉะนั้นจะไม่สามารถเขียนโค้ดที่เข้าใจได้ง่าย
นี่เป็นจุดสิ้นสุดของบทช่วยสอนนี้ฉันหวังว่าคุณจะชอบบทความนี้และได้เรียนรู้สิ่งใหม่ ๆ หากคุณมีคำถามใด ๆ เกี่ยวกับบทความนี้คุณสามารถฝากไว้ในส่วนความคิดเห็นด้านล่างหรือคุณสามารถใช้ฟอรัมอิเล็กทรอนิกส์ของเรา