שְׁאֵלָה:
כיצד יכול ארדואינו להפיק תדר מוביל ספציפי (כלומר 56 קילוהרץ)?
jlbnjmn
2014-02-24 06:55:35 UTC
view on stackexchange narkive permalink

אני עובד על פרויקט אופטיקה בחלל פנוי לשליחת נתונים באופן אלחוטי בין שתי נקודות. כדי להשיג זאת, אני משתמש בנורית IR המחוברת ל- Arduino Uno הדופקת בתדר נשיאה של 56 קילוהרץ עבור המשדר ובארדואינו שני עם מודול גלאי IR 56 קילו-הרץ למקלט.

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

קריאת גליון הנתונים עבור ATmega328 נראה כי יש דרך להגדיר דופק מדויק יותר באמצעות טיימרים של השבב. האם זה אפשרי, ואם כן, כיצד יוצרים דופק של 56 קילוהרץ באמצעות הטיימרים?

מה הדיוק הדרוש לתדר 56KHz שלך? כְּלוֹמַר. איזה טווח תדרים מקובל בפרויקט שלך? אני שואל מכיוון שמשתמשים בטיימרים של ארדואינו בלבד, לדיוק יש מגבלות.
55.5khz עד 56.5khz יהיה אידיאלי על מנת לשמור על רמת תגובה גבוהה בגלאי.
חָמֵשׁ תשובות:
#1
+10
jfpoilpret
2014-02-25 02:45:44 UTC
view on stackexchange narkive permalink

אכן ניתן להפיק אות 56 קילוהרץ עם טיימר ארדואינו.

טיימר למעשה יכול להיראות כרישום מיוחד, ב- MCU, המחזיק ערך (החל מ- 0) שמתגבר בתדר שהוא תדר השעון MCU (16 מגהרץ ב- Arduino Uno), אפשרות מחולקת בגורם הנקרא prescaler . כאשר ערך זה מגיע למגבלה, הנקראת השווה התאמה , שאתה מציין, קורים שני דברים:

  • ערך רישום הטיימר מאופס ל- 0.
  • מתקשרת ל ISR (שיבוש שגרת שירות) פונקציה להתקשרות חוזרת (אתה יכול להגדיר אותה כך שתצביע על הקוד שלך).

הרעיון הוא להשתמש כי ה- ISR ישנה שינוי של הפלט של סיכה לוגית בכל פעם שהוא נקרא ( HIGH , ואז LOW , ואז HIGH ...).

כעת, כדי ליצור גל מרובע של 56 קילוהרץ, תצטרך לקרוא ל- ISR שלך 56000 * 2 פעמים בשנייה ( * 2 מכיוון שאתה צריך לשנות את ערך הפלט פעמיים לתקופה).

אתה יכול לבחור את הערך prescaler שאתה רוצה לטיימר בין הרשימה הבאה:

  • 1 (תדר השעון אינו מחולק, ומכאן 16 מגה-הרץ)
  • 8 (תדר השעון מחולק ב- 8, ומכאן 2 מגה-הרץ)
  • 64
  • 256
  • 1024

ישנם שני גדלים של טיימרים / מונים ב- Arduino Uno (הם e נקרא טיימר / מונה למעשה): 8 ביטים ו -16 ביטים.

ב- Arduino Uno (ATmega328P), יש לך שלושה טיימרים בסך הכל, אך חלקם עשויים לשמש את ליבת Arduino ספריות או ספריות אחרות המשמשות לשרטוטים שלך (תצטרך לבדוק זאת בעצמך):

  • timer0 (8-bit)
  • timer1 (16-bit)
  • טיימר 2 (8 סיביות): לזו יש יותר אפשרויות הגדרה מוגדרת מראש (1, 8, 32, 64, 128, 256 ו- 1024)

עכשיו אתה צריך ליצור גל של 56 קילו-הרץ מ -16 מגה-הרץ, ולכן, בלי להגדיר מראש, יהיה עליך לספור עד:

16000000 / (56000 * 2) - 1 = 141.857 ( - 1 מכיוון שעון טיימר סופר מ- 0 לערך זה ומאפס רק לאחר זה הושג)

מתוך חישוב זה, אנו יכולים לצייר שתי תצפיות:

  1. 141.857 אינו מספר שלם וכך זכית ' לא תוכל ליצור גל של 56 קילוהרץ בדיוק.
  2. ללא קפיצה מוקדמת, אתה צריך טיימר של 16 סיביות מכיוון ש- 285 אינו ניתן לייצוג כמספר שלם לא חתום עם 8 סיביות.

מעתה יש לך שתי אפשרויות:

  1. השתמש בטיימר של 16 סיביות ( טיימר 1 ), השתמש ב- prescaler = 1 ובחר 142 קוד> כהתאם להשוות; שיעניק לך את התדר הבא: 16000000 / (2 * (142 + 1)) = 55944 הרץ
  2. השתמש בטיימר 8 סיביות ( timer0 חזק >), השתמש ב- prescaler = 8 ובחר 17 בתור התאמת השוואה; שייתן פחות דיוק בתדירות הבאה: 16000000 / (8 * 2 * (17 + 1)) = 55555 הרץ שנמצא עדיין בטווח הנדרש.

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

כמובן ש- ATmega328P שלם נתונים חשוב גם אם ברצונך להבין, בפרטי פרטים, מה אתה עושה.

כמה הערות חשובות:

  • ה- ISR מבוצע עם הפרעות נכים ולכן עליו להיות קצר ככל האפשר. בפרט, יש מספר פונקציות מספריית Arduino שלא ייקראו מ- ISR.
  • שעון Arduino Uno אינו מדויק במיוחד (הוא משתמש בתהודה קרמית במקום קוורץ, שהיה יכול להיות הרבה יותר מדויק יותר), ולכן פירוש הדבר שתדירות הפלט תשתנה עוד יותר.
גם כשהמגבלה שצוינה מגיעה * החומרה * יכולה להחליף סיכה. לפיכך אין צורך להשתמש ב- ISR כלל. תמיד יהיה * ריצוד * עם ISR מכיוון שלא ניתן להפריע להוראה ברגע שהיא מתחילה. עם זאת החומרה תמיד תחליף את הסיכה בקצב הרצוי.
מפתיע במקצת שהארדואינו אונו משתמש בתהודה קרמית, אך מקור לכך הוא * [Arduino UNO FAQ] (https://learn.adafruit.com/arduino-tips-tricks-and-techniques/arduino-uno- faq) * (ליד * "האם ה- Uno משתמש בתהודה או גביש לשעון המעבד?" *).
#2
+3
Peter Bloomfield
2014-02-24 18:02:05 UTC
view on stackexchange narkive permalink

מצאתי ש טון () שימושי להפקת פולסים בתדירות גבוהה בכל סיכה. זה אמור להיות מסוגל להתמודד עם 56 קילוהרץ. (עריכה: כפי שצוין על ידי jfpoilpret, הכי קרוב שאפשר להגיע על ארדואינו 16 מגה-הרץ הוא כ- 55.944 קילו-הרץ)

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

כל מה שאתה צריך לעשות זה להעביר את אות הנתונים שלך על סיכה אחרת ואז לשלב אותו עם המוביל באמצעות שער AND. האות המשולב יכול לעבור ישר למשדר ה- IR שלך.

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

לרוב המקבלים תפוקות נמוכות פעילות בדרך כלל. אם אתה מחבר את החלק העליון של נורית הנורית ל- 56khz, ואת התחתית לסיכת הנתונים שלך, כאשר סיכת הנתונים הולכת נמוכה אתה מקבל פלט IR, מה שאמור לגרום למקבל לרדת נמוך. אין צורך בשער, רק הוביל ונגד. הבעיה היחידה מוגבלת לכל מה שסיכות io הנוכחיות יכולות לנהוג.
#3
+2
zzz
2014-04-01 09:10:47 UTC
view on stackexchange narkive permalink

התשובה המקובלת של jfpoilpret כתובה היטב, תקפה לחלוטין וב 99% מהמקרים אעשה בדיוק את מה שהוא מסביר. הפתרונות שלו נמצאים היטב בפרמטרים שהגדרתם, ולכן הם צריכים לעבוד טוב מאוד. אבל מה עדיף על " טוב מאוד "? שלמות! הרי השאלה היא לייצר ערך מדויק. כאמור קרוב מספיק טוב ברוב המקרים (ניתן לטעון בכולם), וגם כאשר מתעסקים במשהו כשעונים כאשר שנייה אחת צריכה להיות שנייה אחת, אתה עדיין צריך לסבול מפגמים בחלקים תורשתיים.

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

עבור אנשים מתקדמים יותר זה כנראה ייראה מילולי מדי ואלם. אבל אני מאמין שאותם אנשים כנראה כבר יודעים זאת ואינם זקוקים לתשובה זו. זה חל גם על כל מיקרו-בקר ועל כל יצרן וארכיטקטורה. אך עבור מיקרו-בקרים אחרים תצטרך להתייעץ עם גליון הנתונים הנכון כדי לברר רישומים מתאימים ולגדול שמות וערכים מראש. למעשה ניתן להשיג קל מאוד kHz (ללא חשבון פגמים מעשיים של החלקים). אז זהו גם מקרה לדוגמא מושלם.

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

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

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

הדוגמה הראשונה היא עם מהירות מחולל טקט נמוכה מדי.

אם תבחר שעון של 56,000 הרץ לא תוכל לעשות דבר כמוך יצטרך להתקשר ל- ISR בכל מחזור ולא יכול לעשות שום דבר אחר. זה חסר תועלת לחלוטין. אם תבחר במהירות גבוהה פי 10 יותר (560 קילוהרץ), יהיו לך 9 (10 מחזורים שהטיימר יגיע לערכו המקסימלי - מחזור אחד להתקשר לפונקציית ISR) מחזורי מיקרו-בקר שיעשו את עבודתך וזה בהחלט אפשרי לא יכול להיות מספיק. לעתים קרובות אתה זקוק לעוצמת חישוב רבה יותר.

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

ל- Arduino Uno R3 המקורי יש שעון מלאי ב- 16 מגה-הרץ, אז כל דבר איטי יותר שמובטח לעבוד. הערך הבא בסדר גודל גדול מ- 56 ונמוך מ- 16 MHz הוא 5.6 MHz. זה יוביל לאפשרות להתקשר ל- ISR כל 50 מחזורים ותיצור תדר טיימר מושלם של 112,000 הרץ. והאות שלך יהיה בדיוק 56 קילוהרץ. יהיו לך 49 מחזורי MCU לביצוע התוכנית שלך בין שיחות ISR, אך עדיין מדובר בסביבות 1/3 מהמהירות של השעון המקורי. אפשר להשתמש ב- 112 כבסיס ולהשתמש בשעון 11.2 מגה-הרץ וזה יתן בערך 2/3 מהדהד 16 מגה-הרץ. פונקציית ה- ISR תיקרא לכל 100 מחזורים ועדיין תיצור אות מושלם של 56 קילוהרץ.

עם זאת, קיימות שתי בעיות עיקריות בערכים אלה.

  • הבעיה הראשונה תלוי מאוד בצרכים שלך: אתה מקריב כ 1/3 (עם 11.2 מגה-הרץ) מכוח החישוב המרבי שלך כדי לקבל את תדר האות המדויק המשתמש בערך רישום קל למצוא (OCR iirc ). יכול להיות שאתה בסדר עם זה או שלא.

  • הבעיה השנייה היא פקק קשה : קל מאוד למצוא ערכים, אבל מאוד לעתים קרובות הם פשוט לא קיימים כמקור שעון מיוצר. זהו דף האינטרנט המהדהד של פרנל שפשוט חסר גם 5.6 מגה הרץ וגם 11.2 מגה הרץ.

כדי לעקוף זאת אנו יכולים התבונן בערכי תהודה זמינים וגלה עוד משהו שניתן להשתמש בו כדי ליצור ערכים רצויים בדיוק. אם נחלק 56 ב -4 נקבל 14 ולמזלנו יש מהוד 14 מגה-הרץ. זה מספק לנו מהירות גבוהה בהרבה ויותר כוח ועם ערך רישום קל לא פחות למצוא. כדי להתקשר ל- ISR 112,000 פעמים בשנייה עלינו לשים ערך של 124 עשרוני או 0x7C הקסדצימלי במרשם ה- OCR, לכן עם ספירת 124 מחזורים + 1 להתקשרות ל- ISR, אנו מקבלים את הערך המושלם הרצוי שלנו.

NB

  1. ISR - שגרת שירות הפסקה (זהו הקוד שמבוצע רק בהפרעות שנוצרו)
  2. עד כמה התוכנית שלך יכולה להיות תלויה בגודל הזיכרון! זה לא קשור למהירות השעון ואין שום קשר לתדירות שאתה מתקשר ל- ISR.
  3. כאשר המיקרו-בקר מתחיל בפקודת התוכנית מונה מונה. אם נוצרת הפרעה, ה- ISR נקרא וערך זה נשמר במרשם מיוחד. לאחר השלמת קוד ה- ISR, משוחזר הערך של דלפק התוכנית מהרשומה המיוחדת הזו והתוכנית ממשיכה מהמקום בו הופרעה כאילו מעולם לא קרה.

    אתן דוגמה מטומטמת ביותר . אם אתה טהרני, אני מזהיר אותך: דימום באף ובעיניים יכול להתרחש.

    דמיין שאתה צריך ללכת מאיפה שהוא איפשהו. הוראות המסלול שלב אחר שלב הן התוכנית הראשית שלך והפקודות שלה. כמה מהר אתה הולך או רץ, תלוי ב"מהירות השעון "שלך, אך לא בהוראות המסלול (30 צעדים קדימה, פנייה אחת 90 ​​דרגה שמאלה, 10 צעדים קדימה, 45 דרגה ימינה וכו ') הם תמיד זהים . עכשיו דמיין ילד קטן או פוליטיקאי מקומי מושחת תאוותני לפתוח את הנעליים מדי פעם. זה האירוע שיוצר הפרעה. ואז אתה נעצר אחרי הצעד האחרון שלך, כורע ברך וקשור את הנעל שלך שוב. זו תוכנית ה- ISR שלך.

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

  4. פחות זה יותר! לא תמיד שעון מהיר יותר. מכשירים שעונים איטית יותר משתמשים בהספק פחות משמעותי. זו יכולה להיות נקודה מכריעה במכשיר המופעל באמצעות סוללה.

  5. המחזורים הדרושים נגזרים מנוסחאות אלה:
    (מהירות שעון / (ערך prescaler * דרוש ISR) תדר שיחות)) - 1

TLDR: הסרת הסרת הלחץ של מתנד הקרמיקה 16 מגה-הרץ והחלפו באחר המאפשר * בדיוק * 56 קילו-הרץ בחלוקה שלמה (למשל 14 מגה-הרץ ומחלקים ב -250).
#4
  0
kiwiron
2014-03-31 14:51:33 UTC
view on stackexchange narkive permalink

ניתן להפעיל ולכבות את הספק פשוט על ידי החלפת מצב סיכת הספק בין פלט לקלט. השתמשתי בזה כדי לשלוט במשאבת חום דרך יציאת האינפרא אדום (שלט רחוק) 37KHz.

#5
  0
kiwiron
2014-04-01 13:12:01 UTC
view on stackexchange narkive permalink

אין צורך להשתמש ב- ISR כדי ליצור את הספק. פשוט הגדר טיימר להפקת פלט PWM של 50% בתדר הספק הנדרש. ה- ISR אחראי רק על ויסות המוביל - בדרך כלל במרווחים של 0.5 או 1 מילימטר - שיעור נוח בהרבה. מניסיוני שגיאה של 5% בתדירות הספק נסבלת על ידי רוב מקבלי ה- IR. השתמשתי ב- Freetronics EtherMega 2560 (שיש בו הרבה טיימרים) אבל אני בטוח שמעבדים אחרים יעשו באותה מידה.

איך בדיוק מיושם אז האפנון של הספק? משנים את מצב פין לכידת פלט הטיימר בין קלט (הספק כבוי) לפלט (הספק מופעל)?


שאלה ותשובה זו תורגמה אוטומטית מהשפה האנגלית.התוכן המקורי זמין ב- stackexchange, ואנו מודים לו על רישיון cc by-sa 3.0 עליו הוא מופץ.
Loading...