תוכן עניינים:

שליטה על טבעת לד של Neopixel עם חיישן מחווה: 3 שלבים (עם תמונות)
שליטה על טבעת לד של Neopixel עם חיישן מחווה: 3 שלבים (עם תמונות)

וִידֵאוֹ: שליטה על טבעת לד של Neopixel עם חיישן מחווה: 3 שלבים (עם תמונות)

וִידֵאוֹ: שליטה על טבעת לד של Neopixel עם חיישן מחווה: 3 שלבים (עם תמונות)
וִידֵאוֹ: מטלה 3 הדלקת מעגל ה- NeoPixel בשיטת "לד רץ", קריאה ערך מחיישן טמפרטורה והצגתו על גבי מסך האפליקציה 2024, נוֹבֶמבֶּר
Anonim
Image
Image
הרכבה והעלאה
הרכבה והעלאה

במדריך זה אנו הולכים לשחק עם חיישן מחוות (APDS-9960) ועם טבעת ניאופיקסל כדי ללמוד כיצד לשלב את שניהם באמצעות UNO Arduino.

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

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

שלב 1: רכיבים

1. ארדואינו UNO

2. כבל USB

3. חיישן מחוות APDS9960 (https://www.sparkfun.com/products/12787)

4. טבעת לד LED 24 neopixel (https://www.adafruit.com/product/1586)

5. כבלי לוח זכר-נקבה, זכר-זכר

6. קרש לחם

7. ספק כוח 5 V לטבעת הלד (אני משתמש בגב 4 סוללות)

8. כדי לחבר את טבעת הניאופיקסל ללוח הלחם תצטרך להלחם אליו שלושה סיכות זכר: GND, PWR וסיכת בקרה. לשם כך תצטרך ברזל הלחמה ושטף

המרכיבים העיקריים כאן הם חיישן מחוות APDS-9960 וטבעת הניאופיקסל 24. אתה יכול להחליף arduinos שונים, ספקי כוח של כבלי USB ולוחות לחם כרצונך.

שלב 2: הרכבה והעלאה

הַרכָּבָה

לפני שתתחיל וודא שיש לך את כל הרכיבים על השולחן שלך. יהיו לנו כמה צעדים נחמדים לבצע:). צירפתי גם את סכמטי Fritzing כתמונה וגם בפורמט fritzing.

1. הלחמה 3 סיכות זכר לטבעת הניאופיקסל (GND, PWR, סיכת בקרה)

2. חבר את טבעת הניאופיקסל ללוח הלחם

3. חבר את חיישן APDS9960 ללוח הלחם

4. חבר את השטח: מארז סוללות, ארדואינו UNO, APDS9960 ונאופיקסל לקרקע לוח הלחם

5. חבר את הכוח: ארדואינו UNO 3V לסיכת החשמל APDS9960, ניאופיקסל לסוללת הסוללה

6. חבר את סיכת הבקרה של neopixel לסיכת D6 של arduino

7. חבר SDA ו- SCL של ה- APDS9960 ל- A4 ו- A5 בהתאמה

8. חבר את סיכת ההפרעה APDS9960 ל- Ddu arduino

העלאת קוד

קודם כל תצטרך להוריד ולהתקין את ספריות הארדואינו הדרושות:

1. ספריית טבעות Neopixel:

2. ספריית חיישן מחוות:

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

לאחר שהורדת והתקנת את הספריות למעלה, תוכל לשכפל או להוריד את מאגר הארדואינים שלי הממוקם כאן: https://github.com/danionescu0/arduino, ונשתמש בשרטוט זה: https://github.com/danionescu0 /arduino/tree/master/projects/neopixel_ring_gestures

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

לבסוף חבר את הארדואינו למחשב באמצעות כבל ה- USB, הכנס סוללות 1.5 וולט לאריזה והעלה את הסקיצה לארדואינו.

שלב 3: איך זה עובד?

בחלק האחרון נלמד כיצד מרכיבים אלה משולבים יחד, כיצד להשתמש בספריות שלהם וכיצד בניתי את הקוד שלי:

ראשית בואו נעיף מבט חטוף בחיישן ובשיטות ה- API של ספריית neopixel שבהן נשתמש

1. Neopixel API מ- adafruit

מספרייה זו נשתמש בשיטות השולטות בצבע הלדים הבודדים וניישם אותן

- כלול את הספרייה:

#לִכלוֹל

- להכריז על הספרייה

#הגדר NEOPIXED_CONTROL_PIN 6

#define NUM_LEDS 24 Adafruit_NeoPixel strip = Adafruit_NeoPixel (NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800);

- לאתחל

#typically בתוך בלוק ההתקנה

הגדרת חלל () {strip.begin (); # אולי יש כאן דברים אחרים #…. }

- הדליקו פיקסלים בודדים ואז החילו את כל השינויים ברצועה (עיבדו אותה בצורה כלשהי)

# הגדר את הפיקסל 0 שיהיה אדום

strip.setPixelColor (0, strip. Color (255, 0, 0)); # הגדר את פיקסל 1 כך שיהיה strip.setPixelColor (1, strip. Color (0, 255, 0)); # הגדר את פיקסל 2 כך שיהיה strip.setPixelColor (2, strip. Color (0, 0 255)); strip.show ();

2. חיישן מחוות APDS 9960

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

- כלול את הספרייה, בדומה ל neopixel

- להכריז על הספרייה כסיכת ההפרעה ועל דגל ההפרעה

#הגדר APDS9960_INT 2

SparkFun_APDS9960 apds = SparkFun_APDS9960 (); int isr_flag = 0;

- אתחל את הספרייה, בדרך כלל בתוך פונקציית ההתקנה

הגדרת חלל ()

{ # הכריז על סיכת ההפרעה כ- INPUT וצירף לה פונקציה pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("האתחול APDS-9960 הושלם"); } else {Serial.println ("משהו השתבש במהלך APDS-9960 init!"); } # לאתחל דברים אחרים אולי}

- הגדר את פונקציית ההפרעה, כאן נקבע רק דגל

void interruptRoutine () {

isr_flag = 1; }

- בתוך פונקציית הלולאה בדוק את הדגל מעת לעת כדי לראות אם זוהה מחווה

לולאת חלל ()

{ # בדוק את הדגל אם (isr_flag == 1) { # אם הדגל מוגדר, הסר את הפסיקה, בצע את העיבוד הדרוש בתוך handleGesture () פונקציה # ולאחר מכן אפס את הדגל והצמד מחדש את interach detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } # אולי קוד אחר כאן אולי}

- הגדר את פונקציית handleGesture () שבה נוכל לבקש את המחווה האחרונה

handle handleGesture () {

# אם אף מחווה אינה תמורה אפשרית, זוהי בדיקה בטוחה רק אם (! apds.isGestureAvailable ()) {return; } # קורא את המחווה האחרונה, משווה עם הידועות ומדפיס מתג הודעות (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); לשבור; מקרה DIR_DOWN: Serial.println ("למטה"); לשבור; מקרה DIR_LEFT: Serial.println ("LEFT"); לשבור; מקרה DIR_RIGHT: Serial.println ("RIGHT"); לשבור; מקרה DIR_FAR: Serial.println ("FAR"); לשבור; }}

עכשיו בואו נראה את כל הקוד בפעולה:

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

האלגוריתם פועל כך:

- לאתחל את הספריות (ראה הקוד למעלה)

- ליצור מערך של עוצמות led הנקראות "ledStates". מערך זה יכיל 24 עוצמות לד המסודרות באופן יורד מ -150 עד 2

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

- הפונקציה "handleGesture ()" בודקת את המחווה האחרונה וקוראת לפונקציה "toggleColor" עבור מחוות UP -DOWN או מגדירה משתנה גלובלי "ledDirection" עבור מחוות LEFT - RIGHT

- הפונקציה "toggleColor ()" פשוט משנה משתנה גלובלי בשם "colorSelection" עם אחד מהערכים 0, 1, 2

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

- "rotateLeds ()" "יסובב" את הנורות קדימה או אחורה באמצעות מערך אחר הנקרא "intermediateLedStates".

"אפקט" הסיבוב ייראה כך:

# לאחר אתחול

{150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # after rotateLeds () נקרא {0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # after rotateLeds () נקרא שוב {0, 0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # וכן הלאה

לשם כך יוצר תחילה את המערך החדש ומעתיק את העוצמות הוותיקות הוותיקות על העמדות החדשות (הגדל את המיקום או הורד אותו). לאחר מכן הוא מחליף את מערך "ledStates" עם "intermediateLedStates" כך שהתהליך ימשיך לאחר עוד 100 אלפיות השנייה.

#כלול "SparkFun_APDS9960.h"

#כלול "Adafruit_NeoPixel.h"

#כלול "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 #define APDS9960_INT 2 #define LED_SPEED_STEP_INTERVAL 100 Adafruit_NeoPixel strip = Adafruit_NeoPixel (NE_LED_, NEOPIX_, NEOPIX_ SparkFun_APDS9960 apds = SparkFun_APDS9960 (); unsigned long lastLedChangeTime = 0; short ledDirection = 0; color colorSelection = 0; בתים ledStates = {150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int isr_flag = 0; הגדרת void () {Serial.begin (9600); Serial.println ("התוכנית התחילה"); strip.begin (); pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("האתחול APDS-9960 הושלם"); } else {Serial.println ("משהו השתבש במהלך APDS-9960 init!"); } lastLedChangeTime = millis (); Serial.println ("Init בהצלחה"); } לולאת חלל () {if (isr_flag == 1) {detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } animateLeds (); } חלל interruptRoutine () {isr_flag = 1; }}; } switch (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); toggleColor (); לשבור; מקרה DIR_DOWN: Serial.println ("למטה"); toggleColor (); לשבור; מקרה DIR_LEFT: ledDirection = 1; Serial.println ("שמאל"); לשבור; מקרה DIR_RIGHT: ledDirection = -1; Serial.println ("ימין"); לשבור; מקרה DIR_FAR: ledDirection = 0; Serial.println ("FAR"); לשבור; }} / ** * שנה את צבע הנוריות הנוכחי * בכל פעם שנקראת פונקציה זו תשנה את מצב leds * / void toggleColor () {if (colorSelection == 0) {colorSelection = 1; } אחרת אם (colorSelection == 1) {colorSelection = 2; } אחרת {colorSelection = 0; }} / ** * האנימציה תפעל לאחר LED_SPEED_STEP_INTERVAL מילי * תחילה נקראת הפונקציה rotateLeds, ואז נקבעים צבעי הלדים באמצעות ה- api * / void animateLeds () {if (millis () - lastLedChangeTime <LED_SPEED_STEP_INTERVAL) {החזרה; } rotateLeds (); for (int i = 0; i <NUM_LEDS; i ++) {strip.setPixelColor (i, getColor (ledStates )); strip.show (); } lastLedChangeTime = millis (); }}, 0, 0} וה ledDirection הוא 1 * ואז לאחר שפונקציה זו נקראת "ledStates" מערך הוא {0, 100, 80, 60, 0, 0} המדמה אפקט סיבוב */ void rotateLeds () {byte intermediateLedStates [NUM_LEDS]; עבור (int i = 0; i <NUM_LEDS; i ++) {intermediateLedStates = 0; } עבור (int i = 0; i <NUM_LEDS; i ++) {if (ledDirection == 1) {if (i == NUM_LEDS -1) {intermediateLedStates [0] = ledStates ; } else {intermediateLedStates [i + 1] = ledStates ; }} אחר {if (i == 0) {intermediateLedStates [NUM_LEDS - 1] = ledStates ; } else {intermediateLedStates [i - 1] = ledStates ; }}} עבור (int i = 0; i <NUM_LEDS; i ++) {ledStates = intermediateLedStates ; }} uint32_t getColor (אינטנסיביות) {switch (colorSelection) {case 0: strip return. Color (עוצמה, 0, 0); מקרה 1: רצועת החזרה.צבע (0, עוצמה, 0); ברירת מחדל: רצועת החזרה.צבע (0, 0, עוצמה); }}

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

מוּמלָץ: