שְׁאֵלָה:
אנימציית RGB LED דיגיטלית
Rhys Edwards
2014-03-14 15:41:10 UTC
view on stackexchange narkive permalink

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

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

האם מישהו מסוגל לכוון אותי לכיוון הנכון?

  #include "LPD8806.h" # כלול "SPI.h" # הגדר רצועה גודל 64int nLEDs = 160; int dataPin = 2; int clockPin = 3; // הפרמטר הראשון הוא מספר הנוריות בגדיל. רצועות הלד // הן 32 נוריות למטר אך ניתן להאריך או לחתוך את הרצועה. שני // הפרמטרים הבאים הם נתוני SPI וסיכות שעון: רצועת LPD8806 = LPD8806 (64, dataPin, clockPin); // באפשרותך להשתמש ב- SPI חומרה לצורך כתיבה מהירה יותר, פשוט השאיר // הפרמטרים של נתונים וסיכה של השעון. אבל זה אכן מגביל את השימוש ל // סיכות ספציפיות מאוד בארדואינו. עבור Arduinos "קלאסיים" (Uno, Duemilanove, // וכו '), נתונים = סיכה 11, שעון = סיכה 13. עבור Arduino מגה, נתונים = סיכה 51, // שעון = סיכה 52. עבור 32u4 Board Breakout + ו- Teensy, data = סיכה B2, // שעון = סיכה B1. עבור ליאונרדו, זה יכול להיעשות רק על סיכות ה- ICSP. // רצועת LPPD8806 = LPD8806 (nLEDs); הגדרת חלל () {// הפעל את רצועת רצועת ה- LED.begin (); // עדכן את הרצועה, כדי להתחיל שכולם 'off' strip.show ();} loop loop () {//turnAllOn(strip.Color(30,30,30),4000); דוהה (0, 127, 0, 100); // אדום, ירוק, כחול, עיכוב - דהה את כל הפיקסלים בצבע אחד //turnAllOn(strip.Color(30,100,30),4000); דוהה (50, 127, 02,100); // אדום, ירוק, כחול, עיכוב - דהה את כל הפיקסלים בצבע אחד //turnAllOn(strip.Color(100,30,100),4000); דוהה (50, 127, 50, 100); // אדום, ירוק, כחול, עיכוב - דהה את כל הפיקסלים בצבע אחד} דהייה בטלה (uint32_t r, uint32_t g, uint32_t b, uint32_t חכה) {int i, j; עבור (j = 0; j < 384; j ++) {
עבור (i = 0; i < strip.numPixels (); i ++) {strip.setPixelColor (i, strip.Color ((r * j) / 1000, (g * j) / 1000, (b * j) / 1000 )); } strip.show (); } עיכוב (המתן);} בטל turnAllOn (uint32_t c, uint32_t חכה) {int i; עבור (i = 0; i < strip.numPixels (); i ++) {strip.setPixelColor (i, c); // הפעל את כל הפיקסלים} strip.show (); // כתוב את כל עיכוב הפיקסלים (המתנה); } גלגל uint32_t (uint16_t WheelPos) {בתים r, g, b; מתג (WheelPos / 128) {case 0: r = 127 - WheelPos% 128; // אדום למטה g = WheelPos% 128; // ירוק למעלה b = 0; // הפסקה כחולה; מקרה 1: g = 127 - WheelPos% 128; // ירוק למטה b = WheelPos% 128; // כחול למעלה r = 0; // הפסקה אדומה; מקרה 2: b = 127 - WheelPos% 128; // כחול למטה r = WheelPos% 128; // אדום למעלה g = 0; // הפסקה ירוקה; } להחזיר (strip.Color (r, g, b));}  
אחד תשובה:
#1
+6
Peter Bloomfield
2014-03-14 16:36:48 UTC
view on stackexchange narkive permalink

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

הגישה שאשתמש בה היא להתחיל בחישוב כמה כל רכיב צריך להשתנות בכל שלב. לדוגמא, אם ברצונך לדעוך מ -100 ל -200 על פני 50 שלבים, עליך לשנות את +2 בכל שלב. אם אתה רוצה לעשות את אותו הדבר לאחור (200 עד 100) אז יהיה עליו לשנות ב -2.

אחת הבעיות היא שכל רכיב כנראה ישתנה בכמות שונה (אולי אדום לעבור מ 0 ל 200, אבל כחול יכול רק לעבור מ 50 ל 70). אם אתה משתמש במספרים שלמים כל הזמן, זה עלול לגרום למעברים לא אחידים, אז אני ממליץ להשתמש בנקודה צפה במקום. זה איטי יותר מבחינה טכנית (פחות יעיל), אבל כנראה לא מספיק לדאוג.

כך כנראה הייתי כותב את זה:

  void fade (uint8_t oldR, uint8_t oldG, uint8_t oldB, uint8_t newR, uint8_t newG, uint8_t newB, uint32_t numSteps, uint32_t waitPerStep) {// השמר מפני חלוקה באפס אם (numSteps == 0) numSteps = 1; // חישב כמה כל צבע צריך לשנות בכל שלב const float stepR = (newR - oldR) / (float) numSteps, stepG = (newG - oldG) / (float) numSteps, stepB = (newB - oldB) / (float) numSteps; // ערכים אלה יאחסנו את הצבעים שלנו בדרך לצוף r = oldR, g = oldG, b = oldB; uint8_t byteR = oldR, byteG = oldG, byteB = oldB; // עברו על כל שלב דהייה const uint16_t numPixels = strip.numPixels (); עבור (uint32_t step = 0; step < numSteps; ++ step) {// העבר צעד אחד לעבר צבע היעד r + = stepR; g + = stepG; b + = שלב B; // לעגל את הצבעים לכדי מספרים שלמים כאן כדי שלא נצטרך לעשות זאת שוב ושוב בלולאה שמתחת לביטר = (uint8_t) (r + 0.5f);
byteG = (uint8_t) (g + 0.5f); byteB = (uint8_t) (b + 0.5f); // החל את הצבע על כל פיקסל עבור (uint16_t פיקסל = 0; פיקסל < numPixels; ++ פיקסל) {strip.setPixelColor (פיקסל, byteR, byteG, byteB); } strip.show (); עיכוב (waitPerStep); }}  

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

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

כדי להשתמש בזה, היית עושה משהו כזה:

  // דהה משחור לאדום והשהה את הקצר (0, 0, 0, 255, 0, 0, 100, 10); השהה (500); // דהה מאדום לסגול והשהה את הקצרה (255, 0, 0, 255, 0, 255, 100 , 10); עיכוב (500); // דהה מסגול לירוק והשהה קצר (255, 0, 255, 0, 255, 0, 100, 10); עיכוב (500);  

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

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

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

ענה טוב מאוד. Kudos לכל פרטי הקוד, האופטימיזציות וההסברים. אולי באג קטן: הצבע מ- לעולם לא מופיע כשאתה מתחיל את הלולאה שלך עם תוספת הצעד הראשון. עליך להוסיף איטרציה נוספת ותוספת רק בסוף הלולאה.
תודה @jfpoilpret. פספוס הצעד הראשון הוא למעשה מכוון. בהתבסס על השאלה, אני מניח שהנוריות כבר מציגות את הצבע 'הישן' לפני שקוראים ל- 'fade ()'. אתה צודק בהחלט. בנסיבות אחרות אולי אכן תרצו את הצעד הנוסף הזה.
זה ממש נהדר. תודה רבה על הכתיבה המפורטת!


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