בעיה שהתעוררה במהלך העבודה הייתה שהשירים התחילו ונגמרו בדיוק על המילישנייה. מה שגרם אי נחת לקוד אשר סובל מתוספות של זמני השהייה ושאר עיכובים כך שלכל זמן שבו שיר מתנגנן יש ספיחים בצורה של זמני השהייה נוספים. הזמנים האלו מצטברים וקשה לפצות עליהם במסגרת הטכנית של הפרוייקט הנוכחי (יש להשתמש בצ'יפ ISD4004 שהוא צ'יפ סאונד עם פנייה ישירה לזיכרון), אבל במסגרת הפרוייקט מצאנו פתרון קלאסי ונחמד, הוספנו זמן השהייה משלנו בסוף כל שיר, כך שיש מרווח בטחון של שקט בסוף כל שיר ואז ההשהייות המצטברות נכנסות בחישוב בתוך הזמן הפנוי שנשאר כך אין מצב של חריגה לשיר אחר ברשימה ובכך שינוי סדר השמעת השירים בעיה שליוותה אותנו לא מעט זמן ונפתרה בסופו של דבר.
יום שני, 7 ביוני 2010
לוגיקה כללית ותנאים סבוכים
ברמת "קבלת ההחלטות" של הפח היו כמה מכשולים שהיינו צריכים לעבור על מנת להביא את הפח ל"אישיות" נכונה והתנהגות מול משתמש טיפוסי, ראשית היה צורך בהגדרת התנאים הבסיסים ואז בדרך שבה הם חופפים.
התנאים:
1. מישהו עובר ליד הפח -> תוצאה -> השיר: לתת
2. מישהו עובר ליד הפח אחרי זמן קצוב (30 שניות) -> השיר: בדד
3. מישהו זורק לפח אשפה -> השיר: תודה
4. מישהו זורק לפח אשפה אחרי זמן קצוב (30 שניות) -> השיר: אש
5. מישהו דוחף את הפח או מזיז אותו מהמקום -> השיר זה הזמן לסלוח.
מכיוון התנאים מופעלים דרך ערכים שמתקבלים מהחיישנים שממוקמים על הפח, ישנה חפיפה בין הקרבה לפח לזריקת אשפה, זאת אומרת אם מישהו מתקרב לפח ורוצה לזרוק, אנחנו לא רוצים להשמיע את שיר המעבר אלא רק את שיר הזריקה, וכאשר יתבצע מעבר בלי זריקה יושמע שיר המעבר.
בנוסף, עניין פרקי הזמן גם היה חשוב ביצירת האישיות של הפח משום שהפח הוא יצור חביב ונחמד שמעניק משירין למי שמתייחס אליו, כאשר אלמנט הזמן הוא קריטי והפח מגיב ביתר התרגשות באמצעות שיר חדש זה מעצים את החוויה אשר הפח נותן.
מערכת התנאים המורכבת לקרבה+זריקה:
כאשר:
dist הוא הערך שמתקבל מחיישן הקרבה
trash הוא הערך שמתקבל מחיישן האור (כניסת זבל לפח)
big time הוא הזמן מרגע הפעלת הפח
last_dist_time ו last_in_time הם הזמנים שנספרים מרגע הפעולות של זריקה או התקרבות.
התנאי:
if (dist<20 || dist1<20)
{
if (trash==0)
{
digitalWrite(inled,HIGH);
if((big_time - last_in_time) / 1000 > 30 && last_in_time!=0) {
gotoTrack(4);
pp();delay(23000);pp();
last_in_time = big_time;
} else if((big_time - last_in_time) / 1000 <30) {
gotoTrack(3);
pp();delay(16500);pp();
last_in_time = big_time;
}
} else {
digitalWrite(inled,LOW);
digitalWrite(distled,HIGH);
if((big_time - last_dist_time) / 1000 >30 && last_dist_time!=0) {
gotoTrack(2);
pp();delay(13000);pp();
last_dist_time = big_time;
} else if((big_time - last_dist_time) / 1000 <30){
gotoTrack(1);
pp();delay(16000);pp();
last_dist_time = big_time;
}
}
if (dist>20 || dist1>20)
{
digitalWrite(distled,LOW);
}
}
{
if (trash==0)
{
digitalWrite(inled,HIGH);
if((big_time - last_in_time) / 1000 > 30 && last_in_time!=0) {
gotoTrack(4);
pp();delay(23000);pp();
last_in_time = big_time;
} else if((big_time - last_in_time) / 1000 <30) {
gotoTrack(3);
pp();delay(16500);pp();
last_in_time = big_time;
}
} else {
digitalWrite(inled,LOW);
digitalWrite(distled,HIGH);
if((big_time - last_dist_time) / 1000 >30 && last_dist_time!=0) {
gotoTrack(2);
pp();delay(13000);pp();
last_dist_time = big_time;
} else if((big_time - last_dist_time) / 1000 <30){
gotoTrack(1);
pp();delay(16000);pp();
last_dist_time = big_time;
}
}
if (dist>20 || dist1>20)
{
digitalWrite(distled,LOW);
}
}
פונקציות! פונקציות! פונקציות!
פונקציית נגן/הרץ קדימה
על מנת להפעיל את נגן המפ3 שחיברנו אל המיקרומעבד, השתמשנו במצמדים פוטואלקטרים 4N27 היחידה מקבלת את האות הדיגיטלי כפי שהוא יוצא מהמיקרומעבד והתזמונים הם קריטים בהפעלת המפסק כי הם צריכים לדמות לחיצה אנושית אך עדיין שתהיה נכונה באופן עקבי (אחרי בדיקות רבות וניסויים רבים ובעזרתו של עמיר הגענו לתזמון של 80/40 מילישניות בהתאמה לזמן כבוי/דלוק) בקוד כתבתי פונקציה שמתאימה ללחיצה על נגן.
void pp()
{
digitalWrite(playpin,HIGH);
delay(80);
digitalWrite(playpin,LOW);
delay(40);
}
{
digitalWrite(playpin,HIGH);
delay(80);
digitalWrite(playpin,LOW);
delay(40);
}
פונקציית העברת שיר באופן יחסי
בנוסף נדרשה לוגיקה אשר מעבירה שירים לפי מיקום השיר הנוכחי והשיר אליו אנחנו רוצים להגיע: הלוגיקה עובדת כך שכאשר מתקיים תנאי מסויים, המכשיר יודע באיזה שיר הוא נמצא באופן דיסקרטי לתנאי שאותו הקוד מקיים ובעקבות כך מפעיל פונקציה אשר בודקת באופן יחסי איפה נמצא השיר ביחס לרשימת השירים בנגן ואז מקדמת את הנגן אל השיר בהפעלת פונקציה דומה לפונקצית נגן שהוצגה קודם אך חוזרת על עצמה כמה פעמים
לדוגמא:
יש 5 שירים סך הכל ברשימה.
אנחנו נמצאים בשיר מס 3 ורוצים להגיע לשיר מס' 3 - נצטרך לעבור 5 שירים שירים
אנחנו נמצאים בשיר מס 3 ורוצים להגיע לשיר מס' 2 - נצטרך לעבור 4 שירים קדימה
אנחנו נמצאים בשיר מס 3 ורוצים להגיע לשיר מס' 1 - נצטרך לעבור 3 שירים קדימה
וכיו"ב בהתאמה.
כך שהפונקציה תהיה:
void gotoTrack(int trackNo) {
if(trackNo > currentTrack) {
skipForward(trackNo - currentTrack);
}
else if(trackNo < currentTrack) {
skipForward(totalTrackCount - currentTrack + trackNo);
} else {
skipForward(totalTrackCount);
}
currentTrack = trackNo;
}
if(trackNo > currentTrack) {
skipForward(trackNo - currentTrack);
}
else if(trackNo < currentTrack) {
skipForward(totalTrackCount - currentTrack + trackNo);
} else {
skipForward(totalTrackCount);
}
currentTrack = trackNo;
}
החלק הראשון והשני של התנאי בודק את המיקום ביחס לשיר הנוכחי והתנאי האחרון בודק אם זהו אותו שיר, בסוף הפונקציה יש עדכון של מס השיר לנתון שמכיל את מספר השיר הנוכחי.
פונקציית בדיקת לדים - הפעלה ראשונית
ברוב המכשירים האלקטרונים קיים מחזור בדיקה ראשוני שפועל כאשר מפעילים מתח למכשיר, הוספתי פונקציה אשר מריצה 5 פעמים מחזור של הדלקה וכיבוי לדים שגם מוסיף לחוויה וגם מאפשר לנו לדעת שהמכשיר תקין.
הפונקציה:
void blip()
{
for(int i=0; i<5; i++){
digitalWrite(inled,LOW);
digitalWrite(distled,HIGH);
delay(100);
digitalWrite(distled,LOW);
digitalWrite(posled,HIGH);
delay(100);
digitalWrite(inled,HIGH);
digitalWrite(posled,LOW);
delay(100);
}
digitalWrite(posled,LOW);
digitalWrite(inled,LOW);
digitalWrite(distled,LOW);
}
יום חמישי, 27 במאי 2010
מה-פח
שלומי הביא פח בנפח של 50 ליטר עם דלת מתנדנדת שצריך לדחוף.
מה שהתגלה כיתרון, כך יכולנו להציב את חיישן האור (LDR) במקביל וקרוב למקור אור חזק - לד לבן, לצורך העניין. הקריאה מהלד גבוהה מאוד וכל התרחקות ממנו עד התרחקות קיצונית תביא לשינוי מהותי בערך שמגיע על המעבד בסופו של דבר נוכל לדעת אם מישהו זורק זבל ומשתמש בפח.
בנוסף חיברנו את חיישן התאוצה- שאנו משתמשים בציר אחד שלו על מנת לזהות תזוזה של הפח וזאת במקרה שמישהו פשוט נותן מכה לפח הפח מזהה זאת ושולח אות למיקרו בקר, היה צריך לכתוב תנאי פשוט אשר בודק כל עוד הפח "ישר" וכל עוד הפח בזוית שהיא לא מיושרת לרצפה.
אני ואליאור ביצענו חיבורי חוטים שיתאימו לאורך הפח והחלטנו על לדים שיתנו חיווי גם לעובדה שהפח עובד וגם לפעולות השונות. מעין תוספת נחמדה לסאונדים שיצטרפו אחכ.
עמיר שמייעץ טכנית לפרוייקט הגיע לאיזון טוב לגבי זמני הורדה והעלאה של האות שדרוש להפעיל את הלחצן נגו והרץ קדימה וקבע אותם על 80 ו40 מילישניות בהתאמה לגבוה ונמוך. אני צירפתי בקוד פונקציות לפעולה נגן ושניה לפעולה הרץ קדימה שמשתמשים בתזמונים האלו ונבדוק את זה בשיעור הקרוב והאחרון.
והנה תמונה של הפח עם קצת יותר אישיות.
יום ראשון, 23 במאי 2010
מי הוא הפח שלנו - איפיון אישיות
כיברת דרך ארוכה נעשתה בחיפוש אחר אישיות לפח המגיב שסביבתו הטבעית אליה הוא הולך להשתייך היא לא אחרת מאשר התחנה המרכזית החדשה.
בפוסטים הקודמים ומתחילת הדרך אנו מנתחים את אופי המקום וכמובן את אופי סוגי האוכלוסיה השונים.
המסקנות העיקריות אליהן הגענו הן:
- מרבית האוכלוסיות החולפות והנמצאות בתחנה הן אוכוסיות קשות יום
- אוכלוסיות הדוברות שפות מגוונות
- האוכלוסיה הדוברת עיברית משתמשת בעיברית פשוטה מובנת ולא מורכבת
האוכלוסיות שלנו הן איProxy-Connection: keep-alive
Cache-Control: max-age=0
7�ן אוכלוסיות יפות נפש אשר פח שיבקש מהן באופן תמים ואקולוגי לא ללכלך ולזרוק בתוכו יעבוד עליהן
אנו מבינים שהצורך הבסיסי הוא לדבר אליהם בגובה העיניים בשפה שהם עצמם דוברים משהו המוכר להם ובא מתוכם.
אישיות רבות חלפו מול פנינו אך סוננו מסיבות רבות:
- פח חברותי ומסתחבק המדבר במילים השגורות בתחנה כגון: "היי אחי כאן כאן למטה!!! גבר אולי תזרוק איזה בדל סיגריה קטן משהו לסיפתח של היום?" או " מצווה, מצווה לזרוק זבל לפח!". זו הייתה האישיות אשר אליה נמשכנו ביותר אך גם הסחבק עצמו צריך להיות בעל אופי מסויים מה שיכול להפיל אותנו "בפח" כאשר הוא יפנה ספציפית לדמות מאופיינת אחת ולא לאחרת.
- פח אשר יגיב וידבר בשפות שונות כגון: "תודה" בתאילנדית "שלום" בהודית ו"כאן כאן למטה!" בשפה אפריקאית אקזוטית אחרת. אישיות זו נפסלה מכיוון ואין לנו דרך לזהות באמת מי הוא החולף על פני הפח שלנו וגם אם היינו רוצים לחשוף אוכלוסיות שונות לשפות חדשות הייתה נוצרת בעיה שחלק גדול מהאנשים פשוט לא היה מבין מה רוצים ממנו ומתעלם או מתעצבן.
- עברנו דרך פח שירותי אשר יציג את עצמו לקהל: " שלום, אני פח זרוק אלי קצת זבל ותשכח", אך זהו פח שבמחשבה שניה מתאים לאזור אחר כמו קניון למשל וכמו כן לאוכלוסיות שיש להן יותר זמן וצורך בשרותיות.
- הפח שלנו אינו יכול להיות פח מטיף כי במוקדם או במאוחר היינו מוצאים אותו במקרה הטוב זרוק באיזו קומה ובמקרה הרע לא היינו מוצאים אותו כלל או מפורק לגורמים.
- פח חברותי אשר פונה אישית לאנשים גם הוא נפסל מאחר ואין אופציה לדעת אם מי שחולף לידו הוא זכר או נקבה ולכן הפנייה צריכה מתוך עצמו בקשה שלו.
הפח שלנו חייב לדבר בשפת המקום, לדבר מתוך עצמו ובאופן שיבוא בטבעיות מחלטת מתוך המקום ומה יותר בא מתוך המקום אם לא מוסיקה!!! מוסיקה היא מאפיין תרבותי אשר פונה לחתך רחב של אנשים שגם במצב שאינם מבינים את הנאמר אינם חשים ניקור לדיבור שלו ואלו שמבינים משתתפים באותה התחושה. מוסיקה פונה לכולם.
עליית לבל אחת היא למצא את המוסיקה המדוייקת לסביבה המסויימת שלנו ומה מתאים יותר מאשר המוסיקה המזרחית שהיא בעצם לב ליבה של התחנה המרכזית החדשה.
לפי האיפיוני דיבור של הפח וסשן התגובות שלו בחרנו שירים לכל סשן ושינינו את המילים על פי מה שהתאים לתגובה שלנו. מצורפות דוגמאות לכמה מן השירים דוגמאות נוספות יעלו בפוסט הבא לאחר הקלטות נוספות.
יום שישי, 21 במאי 2010
חיבור חיישנים לפח
לצורך הניסוי הראשי חיברתי 2 חיישנים, חיישן סונאר לקביעת מרחק של משתמש מהפח וחיישן אור (LDR) לקבוע האם נזרק משהו לתוך הפח. לגבי קביעת המרחק של המשתמש מהפח היה צורך ב-2 חיישנים על מנת ליצור תחום גדול יותר שהפח יוכל "לחוש".
חיבור חיישן האור וחיישני הסונאר לפח
חיישני הסונאר נותנים ערכים משתנים מ0-1023 נכון לעצם רחוק או קרוב כאשר 1023 הוא בעצם חלל פתוח, כך ניתן לקבוע תחום שבו נרצה לדעת האם מישהו התקרב מספיק לפח על מנת להפעיל את הפונקציה היעודית. לאחר שחיברתי את החיישנים מצאתי שהערך 20 הוא תחום של בערך 30 ס"מ מהחיישן.
חיישן האור זקוק לאור מצידו השני על מנת לקבל ערך גבוה מ0 - התקשתי למצוא מקור אור חזק, בסופו של דבר מצאתי לד לבן שמאיר באור חזק אך גם הוא נתן ערכים מקסימלים של 6 (שאור לבן אמור להיות 1023) זה בכל מקרה היה מספק על מנת לקבוע בתנאי האם משהו חצה את התווך שבין החיישן לבין הלד הלבן.
בקוד ביצעתי שני תנאים האחד בודק את התחום לחיישן הסונאר ובהתאמה שולח אות אשר לצורך הניסוי מדליק לד ומפעיל את נגן המוזיקה, התנאי השני מדליק לד אם נזרק משהו לתוך הפח כפי שאפשר לראות בסרטון הבא:
חיבור נגן מוזיקה למעבד
בעקרון, חיבור נגן מוזיקה אמור להיות דבר פשוט, הלחצנים של הפעלה והפסקה העברה קדימה ואחורה יכולים להיות מוחלפים במפסקים או במקרה שלנו רכיב בשם 4N27 הרכיב הוא פוטוטרנזיסטור אופטוקפלר שבעצם מסוגל כמו ממסר לשלוט על זרמים גבוהים ע"י זרמים נמוכים יותר במקרה הזה ע"י דיודה ש"מתקשרת" עם פוטוטרנזיסטור.
מעגל השליטה פשוט:
הבעיה היא בתזמונים כאשר לוחצים על מפסק הזמן שלוקח ללחוץ הוא במילישניות עד 20 מילשניות, הלחיצה שמתבצעת באופן אוטומטי מדויקת מצד אחד אבל יוצרת בעיות עקב מעברי זמן בין הרכיבים השונים לכן היה צריך למצוא את הזמן המדויק שבו יש לעכב את האות מהרגל שיוצאת מהמעבד.
בנוסף, ישנה בעיה בלוגיקה של הנגן עצמו לחיצה אחורה אינה מעבירה שיר אלא מחזירה לתחילת השיר המנוגן, לחיצה קדימה מעבירה שיר אך גם לוחצת באופן אוטומטי על נגן, אלו דברים שיש לקחת בחשבון, הלוגיקה הפשוטה ביותר היא לסדר את השירים אחד אחרי השני ולהתקדם בזה אחר זה ולחזור שוב מתחילת הרשימה.
בשביל ליצור את ההפעלה דרך המעבד אפשר ליצור פונקציות בקוד שהם חיקוי של נגן ושל הרץ קדימה או אחורה.
לדוגמא:
void pp()
{
digitalWrite(skippin,HIGH);
delay(100);
digitalWrite(skippin,LOW);
delay(10);
}
פונקציה זו שולחת במשך 100 מילישניות אות גבוה לרגל המבוקשת ולאחר מכן 10 שניות של אות נמוך
ניתן להשתמש בפונקציה במהלך הקוד כחלק מתנאי המתקבל מאחד החיישנים.
הירשם ל-
רשומות (Atom)