Proiectul meu este realizat cu scopul de a oferi utilizatorului o lista de miscari de urmat pentru a rezolva un cub rubik de dimensiune 2x2x2 amestecat aleatoriu. Acesta va utiliza un singur senzor de culoare pentru a creea o lista de culori are fetelor. Astfel se vor utiliza diverse rotatii ale intregului cub (90 grade in jurul axulul propriu centrl + rasturnare intr-o directie) pentru ca senzorul sa poata detecta cele 24 culori. Am ales acest proiect deoarece cand eram mai mic am fost extrem de pasionat de puzzle-uri, implicit de rezolvarea cubului rubik. Aveam cuburi de diferite dimensiuni, chiar si pana la 9x9x9, fiind interesat de cum scaleaza solutia la cuburi de dimensiuni mai mari.
Acest proiect este util si pentru altii deoarece pot invata diferite metode de rezolvare prin urmarirea pasilor, cat si cel mai important lucru din rezolvarea cubului rubik - notatiile miscarilor algoritmilor (L, R, U, D, B, F).
Functionalitatile prezentate mai sus vor fi indeplinite in urmatorul mod: Cubul va sta initial blocat intre 4 margini putin ridicate, cat sa nu permita miscarea lui. In spatele sau se va afla o “rampa” de care se va utiliza pentru a fi dat peste cap. Acest build va fi asezat pe o platforma mai mare care va fi rotita cu cate 90 grade de un servomotor. Astfel vom putea citi cele 4 fete de deasupra. Pentru a putea schimba fata de deasupra, voi folosi un al doilea servomotor care va fi sub forma de brat. Acesta are scopul sa impinga cubul peste cap pe rampa, urmand ca acesta sa alunece inapoi in locul initial. Astfel prin rotatii de platforma + rostogolori voi putea citi toate cele 6 fete ale cubului, urmand ca algoritmul de rezolvare sa dea miscarile necesare. Datorita asemanarii izbitoare pentru senzorul de culoare ale culorilor rosu si portocaliu de pe cubul meu de test, am lipit adeziv peste portocaliu pentru a putea distinge mai usor.
* Ecran LCD: Vizualizarea miscarilor de urmat pentru rezolvarea cubului.
* Senzor de culoare RGB TCS34725: Utilizat pentru citirea luminii reflectate de o fata si detectarea culorii.
* Motor Pas cu Pas 28BYJ-48 cu Controler ULN2003: Pentru rotirea cu cate 90 grade a platformei. Utilizeaza un driver pentru a putea trage curent suficient fara a arde microprocesorul.
* Motor Pas cu Pas 28BYJ-48 cu Controler ULN2003: Utilizat pentru bratul care va da peste cap cubul rubik.
* Modul tensiune alimentare MB102: Pentru a alimenta driverul ce va da curent motorului ce invarte platforma.
* ATmega324P: Microcontrolerul principal responsabil pentru coordonarea tuturor modulelor.
* Divizor Tensiune : 2 rezistente de 10kohmi pentru a putea trage in microcontroller direct din sursa de 9V o tensiune de 4.5 pentru a detecta bateria ramasa.
* LED-uri si Butoane: Atat pentru debug cat si pentru alte utilizari precum pornirea citirii.
* GND (Atmega, pinii 6/7) legat la GND (Modul MB102, Drivere, Senzor, LCD).
* Motorul 1 (Platforma Rotatie) Pinii folosiți: PD2, PD3, PD4, PD5 legați la IN1, IN2, IN3, IN4 (Driver 1).
Motoarele pas cu pas (stepper) necesită 4 pini digitali pentru a activa succesiv magneții interni.
* Motorul 2 (Bratul) Pinii folosiți: PD6, PD7 și PB0, PB1 legați la IN1, IN2, IN3, IN4 (Driver 2).
A trebuit să folosesc următorii 4 pini digitali disponibili. Deoarece Portul D se termină la PD7, am continuat cu primii doi pini din Portul B.
* Senzorul de Culoare (TCS34725) și Ecranul LCD Pinii folosiți: Ambele componente sunt legate în paralel la aceiași 2 pini:
PC4 legat la pinii SDA (Serial Data) ai LCD-ului și Senzorului.
PC5 legat la pinii SCL (Serial Clock) ai LCD-ului și Senzorului.
Cubul va fi pus pe suportul de carton destinat. O data apasat butonul, robotul va incepe sa faca o secventa de citiri astfel incat fiecare dintre cele 24 fete ale cubului sa fie citite. Acestea vor fi organizate in “fete” care vor fi trimise extern prin serial catre laptop, unde un script python asteapta inputul. Acest lucru a fost facut deoarece modul in care solutia este cautata (printr-un BFS bidirectional) nu permite rularea pe placa datorita memoriei limitate (undeva la 10MB de memorie utilizat in worst case). Scriptul va trimite rezultatul catre placa, care va afisa pe LCD secventa de pasi necesara rezolvarii cubului. Atentie! Pentru rezolvarea corecta a cubului, acesta nu trebuie rotit, secventa este data pentru orientarea cubului obtinuta o data cu finalizarea scanarii.
Pentru 'calibrarea' senzorului de culoare am decis ca este mai util sa lucrez cu procentaje din lumina reflectata, decat cu valorile in sine, deoarece valoarea in sine poate varia extrem de usor datorita luminii ambientale. Astfel prin intermediul procentajelor, indiferent de lumina ambientala, valorile au doar un mic joc, care poate fi surprins printr-o plaja mai mare de valori in if-ul principal fiecarei culori.
Pentru scrierea codului am folosit visual studio code, impreuna cu platform.io.
Singura librarie 3rd party utilizata de mine este <Stepper.h> deoarece cand am incercat sa actionez bobinele pe baza pinilor, pentru a roti motoarele acestea isi pierdeau toata puterea, nemaiputand roti cubul rubik.
Ledul LCD si Senzorul de culoare vor fi activate pe baza scheletului de laborator prin intermediul i2c. Am renuntat la librariile folosite intial: LiquidCrystal_I2C și Adafruit_TCS34725. Ambele componente sunt controlate folosind un driver I2C (TWI), utilizand direct registrii TWCR, TWSR si TWDR.
* Funcție de citire a convertorului Analog-Digital (inlocuieste analogRead) - uint16_t adc_read(uint8_t channel)
* Opreste alimentarea bobinelor pentru a nu se incalzi - void elibereazaMotoare()
* Scrie pe LCD datele de start precum bateria si instructiunile de utilizare - void deseneazaEcranInitial()
*Functie care determina culoarea in functie de datele primite de senzor, trebuie adaptata in functie de lumina ambientala prin teste - char citesteCuloare()
Totodata mai avem functiile specifice Arduino - setup() si loop()
1) GPIO - Butonul de start si stepperele care rotesc cubul
2) ADC - Divizorul de tensiune care va afisa bateria ramasa
3) I2C - Senzorul de culoare cat si LCD
4) Intreruperi/Timere - Delay urile intre rotiri si citiri.
Click here.