การบันทึกเสียง Arduino (Mega): 9 ขั้นตอน (พร้อมรูปภาพ)

การบันทึกเสียง Arduino (Mega): 9 ขั้นตอน (พร้อมรูปภาพ)

สารบัญ:

Anonim

บันทึกเสียง ไปยังการ์ด SD Audino Mega ของคุณ

สามารถเล่นไฟล์เสียงในแอปพลิเคชั่นเสียงมาตรฐานหรือวิเคราะห์ไบต์ต่อไบต์

คำแนะนำนี้จะแสดงให้คุณเห็นว่าสามารถเพิ่มสัญญาณเสียงลงในบัฟเฟอร์ 512 ไบต์ซ้ำแล้วซ้ำอีกและถ่ายโอนไปยังการ์ด SD แบบเรียลไทม์ ระยะเวลาที่บันทึกสามารถเปลี่ยนแปลงได้

อัตราตัวอย่างคือ 9.4 KHz และเอาต์พุตไฟล์ wav 8 บิตโมโน แม้ว่าคุณภาพเสียงจะไม่ดีนัก แต่คุณภาพเสียงก็เพียงพอแล้ว

ไฟล์ wav ที่บันทึกไว้สามารถบันทึกเป็นข้อมูลแบบตาราง นอกจากนี้ยังสามารถแสดงเป็นกราฟเลื่อนอย่างง่ายบนหน้าจอ

ไฟล์ทั้งหมดถูกประทับเวลาโดยใช้รหัสเวลายูนิกซ์ที่ส่งมาจากมอนิเตอร์อนุกรม

แรงบันดาลใจสำหรับบทความนี้มาจากการอ่าน Amanda Ghassaei: http: //www.instructables.com/id/Arduino-Audio-Inp …

อัปเดตโปรแกรมล่าสุดของฉันเมื่อสิ้นสุดการสอนนี้ เพิ่มอัตราตัวอย่างเป็น 19 KHz ด้วยการปรับปรุงที่สำคัญในคุณภาพเสียง

คุณอาจสนใจสอนของฉันเมื่อ:

ความเร็วสูง Arduino Oscilloscope: http: //www.instructables.com/id/Arduino-High-speed …

Pวางไฟล์ wav จาก Arduino: http: //www.instructables.com/id/Arduino-playing-wa …

เทคโนโลยีการ์ด SD ได้พัฒนาไปอย่างหลีกเลี่ยงไม่ได้ ฉันได้ทดสอบกับการ์ด sd Sandisk Ultra 8GB นี่เร็วกว่าการ์ด 4GB ของ Kingston ที่ฉันเริ่มใช้ การใช้ซอฟต์แวร์ที่อัปเดตแล้วของฉันฉันสามารถบันทึกที่ 38.3KHz โดยไม่ทำให้คุณภาพลดลง (2014/04/08)

วัสดุ:

ขั้นตอนที่ 1: ข้อกำหนด

Arduino ล้าน 2560

ส่วนประกอบต่อไปนี้อาจเป็นทางเลือกที่ใช้งานได้ (ด้วยการปรับแต่งโปรแกรม - ฉันขอฝากไว้กับคุณ!)

LCD Keypad Shield http: //www.hobbytronics.co.uk/arduino-lcd-keypad -…

คณะกรรมการฝ่าวงล้อม MicroSD ควบคุมด้วย Logic Conversion V2

http: //www.hobbytronics.co.uk/microsd-card-regula …

การ์ดหน่วยความจำ Micro SD 4GB 4GB: //www.hobbytronics.co.uk/microsd-card-regula …

ไมโครโฟน pre- เครื่องขยายเสียง

ac พร้อมกับตัวแบ่งที่มีศักยภาพในการจัดตำแหน่งแรงดันไฟฟ้าระหว่างราง Arduino 0-5 V

Amanda Ghassaei ได้เผยแพร่วงจรที่ http: //www.instructables.com/id/Arduino-Audio-Inpu …

ฉันออกแบบของตัวเองด้วยการควบคุมเสียงทุ้มเสียงแหลมและระดับเสียง อย่างไรก็ตามมีการออกแบบพรีแอมป์มากมายบนเว็บ

ขั้นตอนที่ 2: ข้อมูลจำเพาะ

รองรับอนุกรม, LCD, SD และหน่วยความจำแฟลช

ชุดอนุกรมที่ 115200 บอด

การประทับเวลาในรูปแบบ Linux จากการตรวจสอบแบบอนุกรม

การป้อนข้อมูลแบบอนุกรมสามารถเริ่มต้นการจับข้อมูลใหม่โดยใช้คำสั่ง 'อีกครั้ง'

การป้อนข้อมูลแบบอนุกรมสามารถตั้งค่าจำนวนของข้อมูลที่อ่าน Kbytes และดังนั้นระยะเวลาของไฟล์เสียงโดยใช้คำสั่ง 'แก้ไข'

เอาท์พุทแบบอนุกรมของข้อมูลหลังจากการร้องขอคำสั่งอินพุต 'อ่าน' - เอาต์พุตสามารถหยุดได้ด้วยคำสั่ง 'q'

กราฟพื้นฐานที่พล็อตบนจอภาพอนุกรม

บันทึกข้อมูลดิบในไฟล์ที่รองรับ wav

ข้อมูลดิบแปลเป็นไฟล์คำสั่ง tabulated 'เขียน'

ทำซ้ำการอัพเดตเวลา 60 วินาทีซ้ำเป็น eeprom LCD หรี่ลงระหว่างการอัพเดตเวลาเป็น eeprom

PWM 3 Square wave พร้อมสำหรับการทดสอบ - สลับกับคำสั่ง 'test'

อินพุต 2 ตั้งค่าหลีกเลี่ยงสูงรอให้กำหนดเวลาอนุกรม

การใช้งานแบบ Uno อาจเป็นไปได้ด้วยการปรับแต่งโปรแกรมรวมถึงการย้ายตำแหน่งไบต์หน่วยเก็บข้อมูลเวลา (ตัวแปร ememory) ฉันปล่อยให้คุณทำงาน

ได้เสียงที่มีคุณภาพดีที่สุดของ NB โดยมีอินพุตแตกต่างกันรอบค่าแรงดันไฟฟ้ากลางที่ 128 นี้เป็นสิ่งสำคัญ!

เอาท์พุท Lcd ของข้อมูลพื้นฐาน

พอร์ต adc ของ Lcd ที่ระบุพร้อมตัวแปร lcdport

การสนับสนุนปุ่มจอแอลซีดี:

เลือกเริ่มต้นตัวอย่างใหม่การเปลี่ยนแปลงซ้ายตัวอย่าง Kbyte หมายเลข - จากนั้นขึ้น +10, ลง -10, ซ้าย -1, ขวา +1

ขั้นตอนที่ 3: การเริ่มต้น

เชื่อมต่อแผงปุ่มกด LCD

เชื่อมต่อเครื่องอ่านการ์ด SD

0, 5V

CLK ถึง pin 52

D0 ถึงพิน 50

D1 ถึง pin 51

CS ถึง pin 53

ฉันติดตั้งตัวอ่าน SD บนแผ่นแถบบิตด้วยหมุดผ่านเพื่อให้ตรงกับจุดเชื่อมต่อที่ต้องการ

(รายละเอียดที่จะปฏิบัติตาม)

คุณอาจต้องการทดสอบเครื่องอ่านการ์ดจอและการ์ด sd โดยใช้สคริปต์ตัวอย่างจากจุดสั่งซื้อ

นี่จะฟังดูเล็กน้อย แต่ก็มีรายละเอียดอื่น ๆ - ที่:

สร้างไมโครโฟนพรีแอมป์และเชื่อมต่อผ่านตัวแบ่งที่อาจเกิดขึ้นตามที่อธิบายโดย Amanda

หรือใช้การออกแบบอื่น

ฉันขอแนะนำให้คุณใส่ตัวต้านทานแบบปรับค่าได้ในส่วนตัวหารที่อาจเกิดขึ้นเพื่อให้สามารถปรับอินพุตอย่างระมัดระวังให้อยู่กึ่งกลางค่าอินพุตที่วัดได้ที่ 128 (ครึ่งหนึ่งของแรงดันไฟฟ้า 0-5) บนพีซีของฉัน "5V" น้อยกว่า 5V เมื่อขับเคลื่อนโดย USB)

หน้าจอ LCD ที่ฉันระบุใช้พอร์ตอะนาล็อกเป็นศูนย์สำหรับปุ่ม LCD เพื่อเชื่อมต่ออินพุตเสียงของคุณกับ A1

ขั้นตอนที่ 4: ติดตั้งเครื่องอ่าน Sdcard

sdcard สามารถติดตั้งได้อย่างง่ายดายบนแผ่นแถบและตั้งอยู่โดยใช้การส่งผ่านหมุด

ฉันใช้ขั้วต่อพินสองชุด (ด้านบนและด้านล่าง) เพื่อทำให้บอร์ดมีเสถียรภาพ

การเชื่อมต่ออยู่ติดกันบน Arduino Mega ดังนั้นแผ่นทองแดงรางติดตามระหว่างการเชื่อมต่อจะต้องเป็น ตัด. ฉันใช้ใบเลื่อยวงเดือนตัดมือจูเนียร์ (ไม่ใช่ในกรอบเลื่อย) โดยมีพินที่หนึ่งล้มลง ให้แน่ใจว่าคุณใช้คุณภาพที่ดี ละเอียด ใบมีดฟัน นอกจากนี้ยังมีประโยชน์อย่างมากสำหรับการทำความสะอาดช่องว่างระหว่างแถบทองแดง ฉันพบว่าการตัดแทร็ก 5V ได้ง่ายขึ้นในขณะที่ตัดสองอันถัดไป (ดูรูปที่ 4) ดังนั้นจึงเป็นเรื่องง่ายที่จะบัดกรีลวดผ่านการตัด

สำหรับหมุดฉันใช้แถบพินมาตรฐาน ความยาวพินในด้านทองแดงถูกปรับให้มีความลึกของซ็อกเก็ต Arduino ก่อนการบัดกรี ความยาวพินสำรองบนชิ้นส่วนด้านข้างถูกตัดและยื่นสะอาดหลังจากการบัดกรี

ตัวเชื่อมต่อหัวต่อแปดทางได้รับการเชื่อมต่อและเสียบตัวเชื่อมต่อแบบ 90 องศาเชื่อมต่อเดือยส่วนเล็ก ๆ ถูกใช้เพื่อรองรับเครื่องอ่าน รูเล็ก ๆ เจาะผ่านมุมของบอร์ดอนุญาตให้สกรูยึดเดือยได้แม้ว่ากาวจะใช้ได้

ฉันเพิ่มส่วนหัวของพินลงในบรรทัด 0V บนบอร์ดสตริป สิ่งนี้ทำให้มั่นใจได้ว่าฉันไม่ได้สูญเสียความพร้อมของจุดเชื่อมต่อ 0V

เครื่องอ่าน SDcard จะต้องมีหัวต่อซ็อกเก็ต 90 องศา

แหล่งจ่ายไฟ 5V สามารถรวบรวมได้ด้วยตัวนำการบินไปยังหนึ่งในพินระหว่าง 21 และ 22 (ทำเครื่องหมาย 5V)

ตรวจสอบว่าคุณได้ตัดทุกแทร็คที่แสดงในภาพรวมถึงแทร็กที่ตัดด้วยสว่าน!

ตรวจสอบรูปแบบและการบัดกรีของคุณ ก่อน เสียบ!

ขั้นตอนที่ 5: รูปแบบไฟล์เวฟ

ส่วนหัวของไฟล์เวฟคือบล็อกขนาด 44 ไบต์

ส่วนหัวอยู่ที่จุดเริ่มต้นของไฟล์ wav

บล็อกส่วนหัวจะต้องเริ่มต้นทั่วโลกด้วย:

wavheader ไบต์ 44;

ข้อมูลเสียงดังต่อไปนี้ส่วนหัว

สำหรับ 8 บิตข้อมูลไฟล์โมโน wav คือตัวเลขระหว่าง 0 ถึง 255

สคริปต์จะอ่านพอร์ต A1 แปลความหมายของเสียงที่เข้ามาเป็นแรงดันไฟฟ้าระหว่าง 0 ถึง 255 Perfect!

จำเป็นต้องอัปเดตเฉพาะ 4 ส่วนของส่วนหัวเมื่อบันทึกไฟล์ wav

เหล่านี้จะแสดงเป็นส่วนที่แสดงความคิดเห็นในภาพ

ไบต์ที่ออฟเซ็ต 4 ประกอบด้วยความยาวของข้อมูล + ความยาวของส่วนหัว - 2 * 4 ไบต์

หรือมากกว่านั้นเพียงแค่นับข้อมูล +36

แต่ละส่วนที่แสดงความคิดเห็นคือหมายเลข 4 ไบต์

สี่ไบต์เกิดขึ้นพร้อมกับไบต์ที่มีนัยสำคัญน้อยที่สุดก่อน - นี่คือ "รูปแบบ endian น้อย"

รูทีนต่อไปนี้จะยอมรับค่ายาวและเขียนไปยังจุดที่ระบุในส่วนหัว wav เป็น 4 ไบต์ที่ประสบความสำเร็จ:

โมฆะ headmod (ค่ายาวตำแหน่งไบต์) {

// เขียนสี่ไบต์เป็นเวลานาน

tempfile.seek (สถานที่); // ค้นหาตำแหน่งในไฟล์

ไบต์ tbuf 4;

tbuf 0 = ค่า & 0xFF; // lo byte

tbuf 1 = (ค่า >> 8) & 0xFF;

tbuf 2 = (ค่า >> 16) & 0xFF;

tbuf 3 = (ค่า >> 24) & 0xFF; // hi byte

tempfile.write (tbuf 4); // เขียนบัฟเฟอร์ 4 ไบต์

}

ขั้นตอนที่ 6: การตั้งค่าอินเตอร์รัปต์ที่อ่านพอร์ตอะนาล็อก

เราสามารถตั้งค่าอินเทอรัปต์เพื่อให้พอร์ตอะนาล็อกหนึ่งพอร์ตถูกอ่านซ้ำ ๆ

(ดูบทความของ Amanda สำหรับรายละเอียดเพิ่มเติม)

รูทีนย่อย "startad" ของฉันใช้สเกลาร์ล่วงหน้า 128 ตัว

สิ่งนี้จะสร้างอินเตอร์รัปต์ซ้ำเพื่อให้พอร์ต A1 อ่านอย่างต่อเนื่องที่ 9.4KHz

รูทีนย่อยขัดจังหวะมีฟังก์ชันสองเท่า:

1) ถ้าเคาน์เตอร์คือ น้อยกว่า จำนวนการอ่าน:

  • เพิ่มไบต์ข้อมูลเสียงลงในบัฟเฟอร์ 512 ไบต์
  • เมื่อบัฟเฟอร์เต็มเขียนบัฟเฟอร์ในครั้งเดียวไปที่ sdcard- 512 ไบต์เป็นขนาดที่เหมาะสมที่สุดสำหรับการบันทึกข้อมูลอย่างรวดเร็ว รีเซ็ตจำนวนบัฟเฟอร์เป็นศูนย์สำหรับไบต์เสียงขาเข้าถัดไป

2) เมื่อตัวนับเป็น เท่ากับ จำนวนที่ต้องการอ่าน:

หยุดการขัดจังหวะที่เกิดขึ้นอีกครั้ง

  • คำนวณระยะเวลาที่กระบวนการใช้ความถี่และอื่น ๆ
  • ใช้ความถี่และขนาดไฟล์เพื่ออัปเดตส่วนหัวไฟล์คลื่น
  • ปล่อยพอร์ตอะนาล็อก A1 และเปิดใช้งานพอร์ต A0 เพื่อให้ปุ่มจอแอลซีดีทำงานได้

ขั้นตอนที่ 7: การตั้งค่าวันที่และเวลาและการบันทึกอย่างไม่ระมัดระวัง

Arduino สามารถติดตามเวลาได้ แต่ต้องบอกจุดเริ่มต้น

เมื่อรีสตาร์ท - จะต้องมีการแจ้งอีกครั้ง (เว้นแต่คุณจะใส่นาฬิกาเวลาจริง)

เวลาสามารถระบุเป็นสตริงเวลา unix- ซึ่งเป็นจำนวนวินาทีที่ผ่านไปตั้งแต่ "ยุคมาตรฐาน 1/1/1970"

คอนโซลอนุกรมสามารถใช้ส่ง T ตามด้วยสตริงเวลา unix

T1403524800 แสดงเวลา 12.00 น. ของวันที่ 3 มิถุนายน 2014

ดูรูทีนย่อย "waitfordate" และ "processSyncMessage"

if (Serial.find (TIME_HEADER)) {// มองหา T

pctime = Serial.parseInt (); // แยกเวลา

if (pctime> = DEFAULT_TIME) {// จำกัด การตรวจสอบว่าเวลาเป็นหลัง default_time

setTime (pctime); // ซิงค์นาฬิกา Arduino กับเวลาที่ได้รับบนพอร์ตอนุกรม

ไซต์นี้มีค่าเวลา unix:

ค่าเวลาสามารถเก็บไว้ในหน่วยความจำแบบ eeprom ซึ่งจะยังคงอยู่หลังจากรีเซ็ต

ค่าที่เก็บไว้เป็นค่าในอดีต - จะไม่ได้รับการอัปเดตระหว่างการรีเซ็ต

อย่างไรก็ตามมันมีประโยชน์เป็นจุดเริ่มต้นสำหรับชื่อไฟล์ใหม่ เมื่อสคริปต์รันโดยไม่มีการประทับเวลาค่าเวลาก่อนหน้านี้จะถูกใช้พร้อมกับการเพิ่ม 60s

writeeeprom และ readeeprom ช่วยให้การจัดเก็บและการดึงสตริงเวลา

เวลาจะถูกเขียนลงในหน่วยความจำแบบ eeprom ทุก ๆ 60 วินาที

โปรดทราบว่าหน่วยความจำแบบ eeprom นั้นมีการ จำกัด การใช้ซ้ำ - แต่ซ็อกเก็ตบอร์ดอาจเสื่อมสภาพก่อน

ขั้นตอนที่ 8: ผลลัพธ์คืออะไรและควบคุมได้อย่างไร

มีการใช้โฟลเดอร์ชื่อ adlog สำหรับข้อมูล

มีเอาต์พุตต่อไปนี้:

1) ไฟล์ wav สำหรับการอ่านแต่ละครั้ง ชื่อไฟล์อยู่ในรูปแบบ ddhhmmss.wav การจับเสียงสามารถทำซ้ำได้ด้วยคำสั่ง "อีกครั้ง"

2) หลังจากคำสั่งซีเรียลคอนโซล "เขียน" ไฟล์ข้อความจะถูกสร้างขึ้นด้วยหมายเลขข้อมูลและค่าข้อมูลในคอลัมน์ นี่คือการคั่นด้วยเครื่องหมายจุลภาคและสามารถนำเข้าสู่โปรแกรมอื่นสำหรับการวิเคราะห์เชิงกราฟ รูปแบบชื่อไฟล์คือ ddhhmmss.txt

3) คำสั่งคอนโซลแบบอนุกรม "อ่าน" สร้างการแสดงกราฟิกแบบเลื่อนในแนวตั้งของเสียง สิ่งนี้สามารถหยุดได้โดยการส่ง "q" จากคอนโซล

ปุ่ม LCD สามารถใช้เพื่อบันทึกไฟล์เสียงใหม่และเปลี่ยนจำนวนไบต์ที่บันทึก เลือกเริ่มไฟล์ใหม่และเริ่มจากฟังก์ชั่น "select" ซึ่งจะอัพเดทหมายเลขข้อมูล พอร์ตจอแอลซีดี A0 ถูกอ่านและขึ้นอยู่กับว่ามีการกดปุ่มขึ้น, ลง, ซ้ายหรือขวาหรือไม่หมายเลขข้อมูลจะถูกเปลี่ยน

คำสั่งคอนโซลอนุกรม "ทดสอบ" สร้างคลื่นสี่เหลี่ยมใน PWM3 สิ่งนี้มีประโยชน์สำหรับการทดสอบที่ไม่มีไมโครโฟนและพรีแอมป์..

หาก PWM2 มีค่าสูงโปรแกรมจะไม่รอการประทับเวลาจากคอนโซลอนุกรม วันที่และเวลาจะไม่เป็นปัจจุบันอีกต่อไป อย่างไรก็ตามสิ่งนี้มีประโยชน์หากไม่ได้เชื่อมต่อ usb

ขั้นตอนที่ 9: อัปเดตโปรแกรม

ฉันเพิ่มความถี่ในการเก็บข้อมูลเป็น 19 KHz สำเร็จแล้ว

สิ่งนี้มีการใช้บัฟเฟอร์ 512byte สองรายการ (การบัฟเฟอร์สองครั้ง) และการเขียนส่วนขัดจังหวะและโมฆะซ้ำ

เสียงดีกว่ามาก

ฉันทดสอบที่ 38 Khz ด้วยผลลัพธ์ที่น่าเชื่อถือ อย่างไรก็ตามที่ช่วงเวลารอบัฟเฟอร์บัฟเฟอร์เป็นครั้งคราวนี้มีอยู่ เป็นไปได้ว่าการปรับปรุงในอนาคตในการออกแบบ SDCard และความเร็วการทำงานของไลบรารี SD จะเอาชนะปัญหานี้ได้ สำหรับผู้ที่ต้องการทดลองดัดแปลง prescalar ตัวแปรก่อนการติดตั้งโมฆะ

ฉันตั้งค่า bufa และ bufb แล้ว

ในชุดคำสั่งขัดจังหวะฉันตั้งค่าสถานะที่เรียกว่า aready - มันเป็นเรื่องจริงเมื่อเขียนถึง bufa เป็นเท็จสำหรับ bufb

ธง writeit เป็นจริงเมื่อจำเป็นต้องมีการเขียนและตั้งค่าเป็นเท็จเมื่อ SdCard เสร็จสิ้น

เมื่อบัฟเฟอร์เต็ม (buffcount == BUF_SIZE):

  • ฉันตรวจสอบว่า Sdcard เขียนเสร็จแล้วซึ่งในกรณีนี้ writeit == false และฉันรีเซ็ตตัวชี้บัฟเฟอร์กลับเป็นศูนย์ให้เปลี่ยนค่าสถานะบัฟเฟอร์เป็นค่าคงที่และตั้งค่าสถานะการเขียนจริง
  • หาก Sdcard ยังคงเขียนอยู่ฉันจะอ่านย้อนกลับหนึ่งครั้ง (bufcount--; และ counter--;) และออกจากการขัดจังหวะ

เมื่อฉันมีจำนวนการอ่านที่ถูกต้องฉันปิดการขัดจังหวะการเขียนบล็อกข้อมูลล่าสุดและเป็นระเบียบเรียบร้อย

ข้อมูลส่วนใหญ่เขียนเป็นโมฆะ:

if (writeit) {// Data พร้อมที่จะเขียน

ถ้า (aready) {

tempfile.write (bufb, BUF_SIZE); // เขียนบล็อกข้อมูลจาก bufb

} อื่น {

// เริ่มต้นการเขียนบล็อกจาก bufa

tempfile.write (bufa, BUF_SIZE); // เขียนบล็อคข้อมูล

}

writeit = false; // แฟล็กที่การเขียนเสร็จสิ้น

}