נגן MP3 מינימליסטי עם CircuitPython

נפח הזיכרון וכוח העיבוד של לוחות הפיתוח המודרניים, בתוספת הספריות המתאימות, מאפשרים לנו לעשות דברים שנחשבו בעבר מטורפים לגמרי – כגון, במגבלות מסוימות, לנגן קובץ MP3 לאוזניות בלי שום רכיבים חיצוניים פרט לנגד אחד. הנה דוגמה.

נגן MP3 פשוט על בסיס לוח פיתוח Xiao RP2040
נגן MP3 פשוט על בסיס לוח פיתוח Xiao RP2040

מודולים להשמעת קובצי MP3 נמצאים איתנו כבר המון זמן. בפשוטים והזולים מביניהם מכניסים כרטיס Micro-SD עם הקבצים, מחברים רמקול קטן, נותנים למודול חשמל ואיזשהו אות טריגר והוא מתחיל לנגן. אם צריך בקרה מורכבת יותר, למשל לנגן קובץ שונה בתגובה לכל אחד מחמישה לחצנים שונים, זה אומר להוסיף מיקרו-בקר, ארדואינו או משהו בסגנון.

לאחרונה קיבלתי משימה דומה, ומטעמי חיסכון במקום פיזי חשבתי לשלוט בנגן באמצעות לוח הפיתוח הקטן והזול Xiao RP2040. אבל אז נזכרתי שעל הלוח עצמו יש רכיב זיכרון FLASH בנפח 2 מגהבייט. האם יש דרך לשמור קבצים על הלוח ושהוא ינגן אותם לבד, בלי מודול ובלי כרטיס זיכרון חיצוניים? בעבר כבר עשיתי דבר כזה, עם מיקרו-בקר PIC עצמאי, וזה עבד יפה – אבל ה"קובץ" שם נשמר בפורמט גולמי ולא-נוח, והיה מוגבל לשניות ספורות בלבד. במקרה הנוכחי הייתי זקוק לשתיים-שלוש דקות.

חיפוש מהיר העלה שאכן, מישהו כתב ל-CircuitPython ספריה להשמעת MP3. המדריך של adafruit לנושא בנוי סביב הלוח Raspberry Pi Pico, אך כידוע ה-Xiao מבוסס על אותו מיקרו-בקר בדיוק ורק חושף פחות פינים שלו. אז בואו נבצע את ההתאמות הדרושות ונראה, או נשמע, מה קורה.

דבר ראשון צריך להתקין על הלוח CircuitPython, שמבוססת על MicroPython (איתה עבדתי עד כה) אבל טיפה שונה בהתנהגות ובספריות. לשם כך, לפני חיבור ה-Xiao ב-USB למחשב* לוחצים ברציפות על לחצן ה-BOOT שלו, ומשחררים אחרי החיבור. הלוח יזדהה בתור כונן חיצוני בשם "RPI-RP2", ואנחנו נעתיק לתוכו את קובץ ה-UF2 שנמצא כאן: https://circuitpython.org/board/seeeduino_xiao_rp2040/ .

*הערה: התהליך הזה נכשל כשחיברתי את הלוח דרך מפצל USB, והצליח רק בחיבור ישיר ליציאת USB במחשב!

תוך שניות ספורות הלוח יעבור למצב עבודה ונוכל להריץ עליו קוד משלנו. סביבת הפיתוח הפשוטה והנוחה לשם כך היא Mu Editor. חשוב לזכור שקובץ הקוד שרץ כברירת מחדל חייב להיקרא code.py.

המדריך אומר להוריד, בנוסף, קובץ zip עם כל מה שדרוש להשמעת MP3, כולל קוד לדוגמה לגרסאות שונות של CircuitPython, אך למעשה אין כאן הבדל בין הגרסאות ואין ספריה מיוחדת – הדבר היחיד שמעניין אותנו ונחוץ לנו הוא הפקודות שמופיעות ב-code.py. שאגב, לא עובד. הקוד מנסה לקשר את אובייקט הנגן לפין שנקרא board.GP0, שאינו מוגדר. הסיבה לכך, מן הסתם, היא שהלוח הוא Xiao והדוגמה מיועדת ל-Pico. אז נריץ את הקוד לזיהוי פינים מתאימים, שנמצא גם הוא במדריך (סעיף "CircuitPython MP3 Capable Pins" בערך שליש מסוף הדף), ונקבל את הפלט שבתמונה:

פלט הקוד לזיהוי פינים מתאימים ל-MP3 על ה-Xiao RP2040
פלט הקוד לזיהוי פינים מתאימים ל-MP3 על ה-Xiao RP2040

שלושת האחרונים לא יעזרו לנו כי הם לא חשופים לשימוש כללי, אבל כל השאר כן, אז נחליף את GP0 מקוד הדוגמה המקורי במי שבא לנו מהרשימה הנ"ל, למשל A0. אם יש לכם תקע לאוזניות, תוכלו לחבר לפינים שלו את GND, ואת A0 דרך נגד (די גדול – צריך לזכור שה-Xiao לא מסוגל להוציא זרם משמעותי), ולשמוע, חלש, את הקבצים. הפלט הוא אמנם PWM ולא אנלוגי, אך הוא נשמע ממש לא רע, יחסית.

סביר להניח שנרצה להעלות לנגן קבצים משלנו. לפי המדריך, אנחנו מוגבלים ל-MP3 עם קצב דגימה 8-24KHz וקצב ביטים 64Kbps לכל היותר. לקחתי קובץ של שיר שאורכו 3 דקות וקצת, ובעזרת התוכנה Audacity הקטנתי את קצב הדגימה (בתפריט Tracks->Resample) וייצאתי כקובץ mono עם Bitrate נמוך יותר (ניתן לבחירה בחלונית הייצוא). אחרי שני סבבים של כוונון הגעתי לגודל קובץ של כ-750 קילובייט, מספיק קטן כדי להיכנס בקלות לזיכרון הפנוי שבלוח – שני מגה פחות המקום ש-CircuitPython בעצמה תופסת.

קובץ השיר המקורי בתוכנה Audacity
קובץ השיר המקורי בתוכנה Audacity

הקוד הבסיסי ביותר, שינגן פעם אחת את הקובץ whatever.mp3 (בהנחה שהעלינו כזה ללוח), נראה ככה:

קוד בסיסי ביותר להשמעת קובץ
קוד בסיסי ביותר להשמעת קובץ

מכאן אפשר לשכלל ולפתח את הקוד לשליטה חכמה ואינטראקטיבית יותר בהשמעת הקבצים. מידע נוסף על הספריות הכלולות ואחרות ב-CircuitPython אפשר למצוא בדפים הרשמיים. מעבר לזה, רוב הסיכויים שבשלב מסוים נרצה גם עוצמת קול משמעותית יותר. לשם כך לא תהיה ברירה אלא להיעזר ברכיב או מודול הגברה חיצוני.

הנגן המינימליסטי
הנגן המינימליסטי (לחצו לתמונה גדולה)

להרשמה
הודע לי על
0 תגובות
Inline Feedbacks
הראה את כל התגובות