This shows you the differences between two versions of the page.
|
pm:prj2023:ncaroi:smart-deskbin [2023/05/27 11:00] teodor.sicoe |
pm:prj2023:ncaroi:smart-deskbin [2023/05/27 12:36] (current) teodor.sicoe |
||
|---|---|---|---|
| Line 16: | Line 16: | ||
| Acest DeskBin are drept functionalitate principala deschiderea automata. Acest lucru se realizeaza in felul urmator: | Acest DeskBin are drept functionalitate principala deschiderea automata. Acest lucru se realizeaza in felul urmator: | ||
| - | * primul senzor ultra-sonic detecteaza mana aflata la o distanta de 5-20 cm | + | * primul senzor ultra-sonic detecteaza mana aflata la o distanta de 5-20 cm |
| - | * acest lucru activeaza servo-motorul care va ridica, actionand printr-un brat de plastic, capacul de la cos | + | * acest lucru activeaza servo-motorul care va ridica, actionand printr-un brat de plastic, capacul de la cos |
| - | * capacul sta deschis timp de 5s, apoi se inchide | + | * capacul sta deschis timp de 5s, apoi se inchide |
| Line 50: | Line 50: | ||
| <note tip> | <note tip> | ||
| - | In schema am inclus adaptorul, deoarece incorporat fiind in componenta, am gasit potrivit sa reprezint strict partea ce contribuie la legare. | + | In schema am inclus adaptorul, deoarece incorporat fiind in componenta LCD, am gasit potrivit sa reprezint strict partea ce contribuie la legare. |
| </note> | </note> | ||
| Line 63: | Line 63: | ||
| Inainte de toate, am definit: | Inainte de toate, am definit: | ||
| - | * macro-uri pentru pinii dedicati | + | * macro-uri pentru pinii dedicati |
| - | * macro-uri pentru constante (distante) | + | * macro-uri pentru constante (distante) |
| - | * variabile globale (array-uri de bytes pentru emoji-uri, variabilele servo si lcd) | + | * variabile globale (array-uri de bytes pentru emoji-uri, variabilele servo si lcd) |
| + | |||
| <note tip> | <note tip> | ||
| Line 73: | Line 75: | ||
| In functia **setup()** realizez urmatoarele: | In functia **setup()** realizez urmatoarele: | ||
| * initializarea display-ului | * initializarea display-ului | ||
| - | * crearea tuturor blocurilor necesare emojiurilor | + | * crearea tuturor blocurilor necesare emoji-urilor |
| * initializarea servo-motorului | * initializarea servo-motorului | ||
| * initializarea pin-urilor pentru INPUT, respectiv OUTPUT | * initializarea pin-urilor pentru INPUT, respectiv OUTPUT | ||
| - | + | In functia **loop()** se urmeaza acest curs de executie: | |
| - | ===== Rezultate Obţinute ===== | + | * pentru **ultrasonic_deschidere**: resetare + masurat distanta --> activare servo |
| + | * pentru **ultrasonic_umplere**: resetare + masurat distanta --> activare LED | ||
| + | * setare emoji in functie de stare | ||
| <note tip> | <note tip> | ||
| - | Care au fost rezultatele obţinute în urma realizării proiectului vostru. | + | **Observatii** \\ |
| + | |||
| + | In cazul senzorului ultrasonic pentru deschidere, daca distanta este intre 5 si 20 cm (parametru calculat in functie de timp), se va apela | ||
| + | **my_servo.write()** pe servomotor. \\ | ||
| + | |||
| + | Iar in cazul senzorului ultrasonic pentru nivelul de umplere, culoarea va fi setata prin **digitalWrite(pin, level)**. Totodata, datorita structurii if din loop, se permite deschiderea automata a cosului doar dca inca este spatiu. | ||
| </note> | </note> | ||
| - | ===== Concluzii ===== | + | Functia **set_emoji()** este apelata ultima in loop, deoarece ea depinde tot ce a fost executat pana atunci. Practic se reevaluzeaza conditiile de umplere si deschidere pentru a afisa pe LCD un emoji definit anterior. Altfel, default va exista un emoji smiley :) |
| - | ===== Download ===== | + | \\ Mai jos atasez codul: |
| + | <code> | ||
| - | <note warning> | + | #include <Servo.h> |
| - | O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). | + | |
| - | Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**. Namespace-ul în care se încarcă fişierele este de tipul **:pm:prj20??:c?** sau **:pm:prj20??:c?:nume_student** (dacă este cazul). **Exemplu:** Dumitru Alin, 331CC -> **:pm:prj2009:cc:dumitru_alin**. | + | #include <Wire.h> |
| - | </note> | + | #include <LiquidCrystal_I2C.h> |
| - | ===== Jurnal ===== | + | #define SERVO 12 |
| + | #define ECHO_PIN_DIST 5 | ||
| + | #define TRIGGER_PIN_DIST 6 | ||
| + | #define ECHO_PIN_FULL 10 | ||
| + | #define TRIGGER_PIN_FULL 8 | ||
| + | #define RED_PIN 2 | ||
| + | #define BLUE_PIN 3 | ||
| + | #define GREEN_PIN 4 | ||
| + | #define FULL 15 | ||
| + | |||
| + | #define MIN_DIST 5 | ||
| + | #define MAX_DIST 20 | ||
| + | |||
| + | // servo | ||
| + | Servo my_servo; | ||
| + | |||
| + | // display | ||
| + | LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display | ||
| + | |||
| + | |||
| + | byte eyeLeftUp[] = { | ||
| + | 0x0F, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10 | ||
| + | }; | ||
| + | |||
| + | byte eyeLeftDown[] = { | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x0F | ||
| + | }; | ||
| + | |||
| + | byte eyeRightUp[] = { | ||
| + | 0x1E, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01 | ||
| + | }; | ||
| + | |||
| + | byte eyeRightDown[] = { | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x1E | ||
| + | }; | ||
| + | |||
| + | byte eyeVerticalLeft[] = { | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10, | ||
| + | 0x10 | ||
| + | }; | ||
| + | |||
| + | byte eyeVerticalRight[] = { | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01, | ||
| + | 0x01 | ||
| + | }; | ||
| + | |||
| + | byte eyeHorizontalUp[] = { | ||
| + | 0x1F, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00 | ||
| + | }; | ||
| + | |||
| + | byte eyeHorizontalDown[] = { | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x1F, | ||
| + | 0x1F, | ||
| + | 0x1F, | ||
| + | 0x1F, | ||
| + | 0x1F, | ||
| + | 0x1F | ||
| + | }; | ||
| + | |||
| + | |||
| + | byte smileyMouth[] = { | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x10, | ||
| + | 0x11, | ||
| + | 0x0E | ||
| + | }; | ||
| + | |||
| + | byte eatingMouth[] = { | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x0E, | ||
| + | 0x11, | ||
| + | 0x11, | ||
| + | 0x11, | ||
| + | 0x11, | ||
| + | 0x0E | ||
| + | }; | ||
| + | |||
| + | byte sleepyEye[] = { | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x1F, | ||
| + | 0x1F | ||
| + | }; | ||
| + | |||
| + | byte satiatedMouth[] = { | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00, | ||
| + | 0x00 | ||
| + | }; | ||
| + | |||
| + | // Reset trigger to LOW | ||
| + | void reset_trigger(int trigger_pin) | ||
| + | { | ||
| + | digitalWrite(trigger_pin, LOW); | ||
| + | delayMicroseconds(5000); | ||
| + | digitalWrite(trigger_pin, HIGH); | ||
| + | delayMicroseconds(5000); | ||
| + | digitalWrite(trigger_pin, LOW); | ||
| + | } | ||
| + | |||
| + | void createSatiatedMouth() { | ||
| + | lcd.createChar(12, satiatedMouth); | ||
| + | } | ||
| + | |||
| + | void printSatiatedMouth() { | ||
| + | lcd.setCursor(9, 3); | ||
| + | lcd.write(12); | ||
| + | } | ||
| + | |||
| + | void createSmileyMouth() { | ||
| + | lcd.createChar(9, smileyMouth); | ||
| + | |||
| + | } | ||
| + | |||
| + | void printSmileyMouth() { | ||
| + | lcd.setCursor(9, 3); | ||
| + | lcd.write(9); | ||
| + | } | ||
| + | |||
| + | |||
| + | void createOpenMouth() { | ||
| + | lcd.createChar(10, eatingMouth); | ||
| + | } | ||
| + | |||
| + | void printOpenMouth() { | ||
| + | lcd.setCursor(9, 3); | ||
| + | lcd.write(10); | ||
| + | } | ||
| + | |||
| + | |||
| + | void createSleepyEye() { | ||
| + | lcd.createChar(11, sleepyEye); | ||
| + | } | ||
| + | |||
| + | void printSleepyEye(int val) { | ||
| + | |||
| + | int i = val; | ||
| + | |||
| + | lcd.setCursor(i + 3, 2); | ||
| + | lcd.write(11); | ||
| + | lcd.setCursor(i + 4, 2); | ||
| + | lcd.write(11); | ||
| + | } | ||
| + | |||
| + | void printSleepyEyes() { | ||
| + | printSleepyEye(0); | ||
| + | printSleepyEye(12); | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | // construct every component of emoji | ||
| + | void createNormalEye() { | ||
| + | |||
| + | lcd.createChar(1, eyeLeftUp); | ||
| + | |||
| + | lcd.createChar(2, eyeLeftDown); | ||
| + | |||
| + | lcd.createChar(3, eyeRightUp); | ||
| + | |||
| + | lcd.createChar(4, eyeRightDown); | ||
| + | |||
| + | lcd.createChar(5, eyeVerticalLeft); | ||
| + | |||
| + | lcd.createChar(6, eyeVerticalRight); | ||
| + | |||
| + | lcd.createChar(7, eyeHorizontalUp); | ||
| + | |||
| + | lcd.createChar(8, eyeHorizontalDown); | ||
| + | |||
| + | |||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | void printNormalEye(int val) { | ||
| + | int i = val; | ||
| + | |||
| + | |||
| + | lcd.setCursor(i + 2, 0); | ||
| + | lcd.write(1); | ||
| + | |||
| + | |||
| + | lcd.setCursor(i + 2, 2); | ||
| + | lcd.write(2); | ||
| + | |||
| + | |||
| + | lcd.setCursor(i + 5, 0); | ||
| + | lcd.write(3); | ||
| + | |||
| + | |||
| + | lcd.setCursor(i + 5, 2); | ||
| + | lcd.write(4); | ||
| + | |||
| + | |||
| + | lcd.setCursor(i + 2, 1); | ||
| + | lcd.write(5); | ||
| + | |||
| + | |||
| + | lcd.setCursor(i + 5, 1); | ||
| + | lcd.write(6); | ||
| + | |||
| + | |||
| + | lcd.setCursor(i + 3, 0); | ||
| + | lcd.write(7); | ||
| + | lcd.setCursor(i + 4, 0); | ||
| + | lcd.write(7); | ||
| + | |||
| + | |||
| + | lcd.setCursor(i + 3, 2); | ||
| + | lcd.write(8); | ||
| + | lcd.setCursor(i + 4, 2); | ||
| + | lcd.write(8); | ||
| + | } | ||
| + | |||
| + | void printNormalEyes() { | ||
| + | printNormalEye(0); | ||
| + | printNormalEye(12); | ||
| + | } | ||
| + | |||
| + | |||
| + | /* print emojies functions */ | ||
| + | void printEatingEmoji() { | ||
| + | printNormalEyes(); | ||
| + | printOpenMouth(); | ||
| + | } | ||
| + | |||
| + | void printSleepingEmoji() { | ||
| + | printSleepyEyes(); | ||
| + | printOpenMouth(); | ||
| + | } | ||
| + | |||
| + | void printSmileyEmoji() { | ||
| + | printNormalEyes(); | ||
| + | printSmileyMouth(); | ||
| + | } | ||
| + | |||
| + | |||
| + | void printSatiatedEmoji() { | ||
| + | printNormalEyes(); | ||
| + | printSatiatedMouth(); | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | void setup() | ||
| + | { | ||
| + | // initialize the lcd | ||
| + | lcd.init(); | ||
| + | lcd.backlight(); | ||
| + | lcd.clear(); | ||
| + | |||
| + | // init face components | ||
| + | createNormalEye(); | ||
| + | createSleepyEye(); | ||
| + | createSmileyMouth(); | ||
| + | createOpenMouth(); | ||
| + | createSatiatedMouth(); | ||
| + | |||
| + | // init servo | ||
| + | my_servo.attach(SERVO); | ||
| + | |||
| + | // init open ultrasonic sensor | ||
| + | pinMode(TRIGGER_PIN_DIST, OUTPUT); | ||
| + | pinMode(ECHO_PIN_DIST, INPUT); | ||
| + | |||
| + | // init full ultrasonic | ||
| + | pinMode(TRIGGER_PIN_FULL, OUTPUT); | ||
| + | pinMode(ECHO_PIN_FULL, INPUT); | ||
| + | |||
| + | // init rgb led | ||
| + | pinMode(RED_PIN, OUTPUT); | ||
| + | pinMode(GREEN_PIN, OUTPUT); | ||
| + | pinMode(BLUE_PIN, OUTPUT); | ||
| + | |||
| + | delay(100); | ||
| + | Serial.begin(9600); | ||
| + | } | ||
| + | |||
| + | float get_distance(int echo_pin) | ||
| + | { | ||
| + | float dist; | ||
| + | |||
| + | // set pin | ||
| + | pinMode(echo_pin, INPUT); | ||
| + | |||
| + | // get distance to hand | ||
| + | long duration = pulseIn(echo_pin, HIGH); | ||
| + | // distance in cm (converted from time) | ||
| + | dist = duration / 58.82; | ||
| + | return dist; | ||
| + | } | ||
| + | |||
| + | void open_trash_by_hand(float dist) | ||
| + | { | ||
| + | int pos; | ||
| + | |||
| + | if (dist <= MAX_DIST && dist >= MIN_DIST) { | ||
| + | pos = 90; | ||
| + | my_servo.write(pos); | ||
| + | delay(50); | ||
| + | } | ||
| + | else { | ||
| + | pos = 0; | ||
| + | my_servo.write(pos); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // check if deskbin is full | ||
| + | void check_content(float dist_full) { | ||
| + | if (dist_full <= FULL) { | ||
| + | // turn red led on | ||
| + | digitalWrite(RED_PIN, HIGH); | ||
| + | digitalWrite(GREEN_PIN, LOW); | ||
| + | } | ||
| + | else { | ||
| + | // turn green led on | ||
| + | digitalWrite(RED_PIN, LOW); | ||
| + | digitalWrite(GREEN_PIN, HIGH); | ||
| + | delay(1000); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void set_emoji(int dist_hand, int dist_full) { | ||
| + | if (dist_full <= FULL) { | ||
| + | printSatiatedEmoji(); | ||
| + | delay(100); | ||
| + | } else if (dist_hand <= MAX_DIST && dist_hand >= MIN_DIST) { | ||
| + | printEatingEmoji(); | ||
| + | delay(500); | ||
| + | } else { | ||
| + | printSmileyEmoji(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void loop() | ||
| + | { | ||
| + | /* full ultrasonic */ | ||
| + | // reset | ||
| + | reset_trigger(TRIGGER_PIN_FULL); | ||
| + | |||
| + | // get dist(sensor, garbage) | ||
| + | float dist_full = get_distance(ECHO_PIN_FULL); | ||
| + | |||
| + | |||
| + | // activate led depending on status | ||
| + | check_content(dist_full); | ||
| + | |||
| + | float dist_hand; | ||
| + | |||
| + | if (dist_full <= FULL) { | ||
| + | // is full | ||
| + | } else { | ||
| + | /* open sensor*/ | ||
| + | // reset | ||
| + | reset_trigger(TRIGGER_PIN_DIST); | ||
| + | |||
| + | // get dist(sensor, hand) | ||
| + | dist_hand = get_distance(ECHO_PIN_DIST); | ||
| + | |||
| + | // activate servo if dist_hand in range(MIN_DIST, MAX_DIST) | ||
| + | open_trash_by_hand(dist_hand); | ||
| + | } | ||
| + | |||
| + | /* set emoji */ | ||
| + | set_emoji(dist_hand, dist_full); | ||
| + | } | ||
| + | |||
| + | </code> | ||
| + | |||
| + | |||
| + | ===== Rezultate Obţinute ===== | ||
| <note tip> | <note tip> | ||
| - | Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. | + | Smart Deskbin-ul proiectat este unul complet functional, care, pentru o functionare foarte lina, responsive, ar avea nevoie de un surplus de tensiune pe anumite componente, deoarece alimentandu-le de la acelasi 5V, pot aparea intarzieri de reactie. |
| </note> | </note> | ||
| + | |||
| + | Cand exista spatiu si este in asteptare, apare **smiley_emoji**, iar ledul este **verde**\\ | ||
| + | {{ :pm:prj2023:ncaroi:stc_smiley_emoji.jpg?400 |}} | ||
| + | |||
| + | Cand este deschis, apare **eating_emoji** \\ | ||
| + | {{ :pm:prj2023:ncaroi:stc_eating_emoji.jpg?400 |}} | ||
| + | |||
| + | |||
| + | Cand nu mai exista spatiu, apare **satiated_emoji**, iar ledul devine **rosu** \\ | ||
| + | {{ :pm:prj2023:ncaroi:stc_satiated_emoji.jpg?400 |}} | ||
| + | |||
| + | |||
| + | Iar aici, alte detalii | ||
| + | |||
| + | {{ :pm:prj2023:ncaroi:stc_interior_deskbin.jpg?400 |}} \\ | ||
| + | |||
| + | {{ :pm:prj2023:ncaroi:stc_right_side_deskbin.jpg?400 |}} | ||
| + | |||
| + | ===== Concluzii ===== | ||
| + | Realizarea acestui proiect a fost o experienta frumoasa si utila. A fost primul meu proiect cu micro-controller si pot spune ca este un sentiment rewarding in final. \\ | ||
| + | Principala dificultate pe care am intampinat-o a fost gasirea pe internet a modului de legare pentru un LCD 2.8 inch ILI9341, fara pin CS. Drept urmare, am gasit alternativa LCD 2004A IIC, care s-a pretat foarte bine genului de aplicatie al proiectului. | ||
| + | |||
| + | |||
| ===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||
| <note> | <note> | ||
| - | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | + | Listă cu documente, datasheet-uri, resurse Internet folosite: |
| + | * emoji blocks: https://maxpromer.github.io/LCD-Character-Creator/ | ||
| + | * legare LCD: https://www.youtube.com/watch?v=F9IVtKa8C7Q&ab_channel=educ8s.tv | ||
| + | * alte detalii: https://www.youtube.com/watch?v=9yrP1CZN3Ds&ab_channel=IndianLifeHacker | ||
| </note> | </note> | ||
| + | |||
| <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | ||