This is an old revision of the document!
Cartografiere 3D a unui teren
Introducere
Proiectul propune realizarea unui sistem automatizat de cartografiere a suprafețelor, folosind un microprocesor Arduino, un senzor de distanță și un mecanism de scanare pe două axe. Măsurătorile realizate sunt afișate real-time prin intermediul unui ecran LCD, iar la final o aplicație specializată realizează un heat-map și o replică 3D a terenului scanat.
Scopul principal este de a construi un instrument portabil și intuitiv pentru analiza formelor de relief la scară mică, combinând vizualizarea imediată cu interpretarea detaliată pe calculator.
Ideea este inspirată dintr-o demonstrație văzută pe Internet, ce implica o hartă din nisip cu diferite forme de relief și un proiector care colora nisipul în diferite culori pentru a distinge între înălțimile terenului. Această aplicație era folosită pentru a învăța copiii să citească hărțile bazate pe înălțimi și adâncimi prin vizualizarea schimbărilor în timp real.
Consider că un astfel de proiect ar fi util atât pentru scopul prezentat mai sus, de prezentare interactivă a creării unei hărți, dar și pentru observarea imperfecțiunilor sau a diferențelor de nivel de pe o suprafață de dimensiuni reduse.
Descriere generală
Componente hardware:
Un microprocesor – pentru coordonarea tuturor operațiilor
Un senzor de distanță – pentru măsurarea variațiilor de înălțime
Un sistem de scanare pe două axe – bazat pe două motoare
Un ecran LCD 1602 I2C – pentru reprezentarea real-time a datelor măsurate
Un laptop– pentru prelucrarea extinsă a datelor și afișarea detaliată a heatmap-ului
Interacțiune hardware - software
Scanare: Senzorul de distanță, montat pe un mecanism de scanare cu două axe, măsoară distanța față de suprafață în puncte discrete organizate sub forma unei matrice.
Procesare locală: Aceste măsurători sunt transmise pe laptop, care realizează o serie de calcule pentru a transforma semnalul primit de la senzor în distanță de la suprafață până la senzor.
Transmitere date: Valoarea fiecărei măsurători este afișată pe ecranul LCD, dar și în Serial Monitor, de unde un script de Python preia datele pentru a crea un heatmap și un model 3D
Vizualizare digitală: Pe laptop, un software dedicat procesează datele primite și construiește un heat-map complet, dar și o replică 3D, oferind o reprezentare vizuală detaliată a terenului analizat.
+----------------------+
| Sistem de scanare |
| (motoare pas cu pas) |
+---------+------------+
|
v
+----------------------+
| Senzor de distanță |
+---------+------------+
|
v
+-------------------+
| Microprocesor |
+---+----------+----+
| |
v v
+-----------------+ +------------------+
| Ecran LCD | | Laptop |
| Afișare locală | | Afișare digitală |
+-----------------+ +------------------+
Hardware Design
Listă de componente:
2 x motoare pas cu pas 28BYJ-48 cu drivere ULN2003
1 x senzor de distanță ultrasonic HC-SR04
1 x ecran LCD 1602 cu interfață I2C
1 x placă de dezvoltare compatibilă Arduino Uno R3
1 x breadboard
1 x laptop (pentru colectarea datelor și procesare)
1 x sistem de axe imprimat 3D
Elemente de susținere realizate din carton (pentru structură și fixare)
Fire pentru conectarea pinilor
Descrierea sistemului mecanic
Sistemul este proiectat pentru a realiza o scanare pe suprafața unei zone plane, utilizând un senzor de distanță ultrasonic montat pe o platformă mobilă în două direcții (Ox și Oy). Mișcarea bidimensională este asigurată de două motoare pas cu pas 28BYJ-48, fiecare fiind responsabil pentru deplasarea senzorului pe una dintre axe.
Mecanismul de transmisie pentru fiecare axă este realizat din roți dințate (gear train), integrate într-un cadru imprimat 3D. Axele au o lungime de aproximativ 30 cm. Axa Oy este fixată pe un suport din carton, astfel încât capetele axei rămân staționare, iar motorul de pe această axă deplasează întregul ansamblu mobil (slider) de-a lungul direcției verticale (în planul scanării).
Pe acest slider este montată și axa Ox, permițând astfel deplasarea senzorului și în direcția orizontală. Ansamblul funcționează ca un sistem de coordonate cartezian, în care senzorul este poziționat succesiv deasupra fiecărui punct dintr-o matrice 2D, în scopul măsurării distanței față de suprafață.
Modul de funcționare
Senzorul parcurge o matrice de 20×20 puncte de măsurare, urmând o traiectorie „linie cu linie”, similară cu următoarea ordine:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
La fiecare punct, senzorul măsoară distanța față de suprafață, iar valorile sunt afișate în timp real pe un ecran LCD și transmise prin portul serial către un computer, unde pot fi salvate sub formă de fișier și ulterior prelucrate (de exemplu, pentru generarea unei hărți de înălțime).
Estetică și stabilitatea mecanică
Un aspect important întâmpinat în timpul realizării sistemului a fost dezechilibrul axei Ox la extindere maximă, cauzat de greutatea motoarelor. Inițial, masa motoarelor afecta distribuția forței, determinând înclinarea platformei mobile. Problema a fost rezolvată prin reconfigurarea poziționării:
Axa Oy a fost montată cu motorul orientat în jos, fixată într-un suport rigid de carton.
Axa Ox a fost montată cu motorul în partea superioară a structurii, astfel încât greutatea acestuia să contribuie la stabilitate și să prevină balansarea nedorită.
Pentru a menține axa Ox cât mai paralelă cu suprafața de scanat, a fost adăugat un element de sprijin din carton, care funcționează ca o bară de susținere orizontală.
Componentele electronice, precum placa Arduino și breadboard-ul, au fost ascunse în spatele unui panou de carton , pe care este montat și afișajul LCD. Acest design asigură un aspect ordonat, oferind totodată protecție componentelor. Placa de dezvoltare este montată într-o carcasă de plexiglas pentru siguranță și vizibilitate parțială.
Software Design
Software-ul proiectului este împărțit în două componente:
Codul Arduino – controlează mișcarea fizică a senzorului și colectează datele de la senzorul de distanță, pe care le transmite către un PC și le afișează pe un ecran LCD.
Codul Python – procesează datele primite și generează vizualizări (heatmap 2D și reprezentare 3D a terenului).
Arduino
Biblioteci utilizate
Arduino.h - inclusă automat și oferă suport pentru funcțiile setup() și loop().
LiquidCrystal_I2C.h 1.1.4 - permite controlul unui ecran LCD 1602 cu interfață I2C, ceea ce reduce numărul de pini folosiți pe Arduino.
Stepper.h 1.1.3 - biblioteca standard pentru controlul motoarelor pas cu pas în configurație 4-wire.
Wire.h - gestionează protocolul I2C pentru comunicarea cu ecranul LCD. Este necesară implicit pentru LiquidCrystal_I2C.
EEPROM.h - permite citirea și scrierea în memoria EEPROM a plăcii Arduino.
Variabile globale și inițializare
LiquidCrystal_I2C lcd(0x27, 16, 2) - inițializează LCD-ul I2C pe adresa 0x27, cu 2 rânduri și 16 coloane.
const int trigPin = 3, echoPin = 2 - pinii conectați la senzorul HC-SR04 pentru generarea și recepția semnalului ultrasonic.
Stepper motorX(…), motorY(…) - motoarele pas cu pas pentru deplasarea pe axele X și Y.
const int gridSize = 20 - dimensiunea matricei de scanare (20×20 puncte).
stepPerCellX și stepPerCellY - numărul de pași necesari pentru ca senzorul să se deplaseze o poziție în grid.
currentX, currentY - poziția curentă a senzorului în grid, salvată în EEPROM.
Funcția setup()
Inițializează comunicarea serială, ecranul LCD, motoarele și pinii senzorului.
Citește poziția salvată anterior din EEPROM pentru a putea relua o scanare întreruptă.
Afișează pe ecran poziția de la care se va relua scanarea („Resume from:”).
Funcția loop()
Parcurgerea matricei:
for (int y = currentY; y < gridSize; y++) {
for (int x = (y == currentY ? currentX : 0); x < gridSize; x++) {
Măsurarea distanței:
do {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2;
real_distance = 8 - distance;
if (lastDistance != 0) {
if (real_distance - lastDistance < 2 && real_distance - lastDistance > -2)
real_distance = lastDistance;
}
Afișarea și trimiterea de date:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(“X:”); lcd.print(x);
lcd.print(” Y:”); lcd.print(y);
lcd.setCursor(0, 1);
lcd.print(“Dist: ”); lcd.print(real_distance); lcd.print(” cm”);
Serial.print(x); Serial.print(” ”);
Serial.print(y); Serial.print(” ”);
Serial.println(real_distance);
Salvarea progresului în EEPROM:
EEPROM.put(0, x + 1);
EEPROM.put(sizeof(int), y);
Mișcarea senzorului:
La final de rând:
Finalizarea scanării
După finalizarea completă a gridului, se șterg datele salvate în EEPROM și se mută senzorul înapoi în poziția de start (0, 0).
Python
Configurarea serială
SERIAL_PORT = 'COM5'
BAUD_RATE = 9600
GRID_SIZE = 20
Inițializare matrice și conexiune serială
Se creează o matrice de 20×20 care va fi completată cu valorile măsurate.
Se inițializează conexiunea serială.
Pauza de 2 secunde permite Arduino-ului să repornească și să fie gata de transmisie.
Colectarea datelor de la Arduino
Se citește fiecare linie trimisă prin Serial.print() de Arduino.
Se parsează poziția X, Y și distanța măsurată.
Datele sunt stocate în matrice, inversând pozițiile pentru ca linia să corespundă axei Y și coloana axei X.
Când poziția (19, 19) este atinsă, se consideră că matricea este completă.
Salvarea datelor într-un fișier
Vizualizare – Heatmap
Se convertesc datele în format NumPy pentru procesare rapidă.
Se „aplatizează” datele pentru a putea fi procesate de funcția gaussian_kde() din scipy.
Se folosește o funcție de densitate gaussiană pentru a obține o suprafață netedă bazată pe înălțimi: weights=z înseamnă că punctele cu înălțime mai mare influențează mai mult forma finală.
Se creează două heatmap-uri: unul pentru a avea legendă (cbar) corectă, altul pentru reprezentarea grafică propriu-zisă.
Se adaugă contururi (contour) pentru claritate.
Se inversează axa Y pentru ca (0,0) să fie în colțul stânga-sus.
Vizualizare - Reprezentare 3D interactivă
Se folosește plotly.graph_objects pentru a genera o suprafață 3D.
colorscale='Plasma' menține coerența culorilor cu heatmap-ul 2D.
Setările includ titlurile axelor, scalarea și aspectul 3D.
Utilizatorul poate roti și mări/mișca suprafața cu mouse-ul.
În final, după scanarea terenului, programul afișează automat cele două grafice ce prezintă schimbările de formă ale terenului țintă.
Rezultate Obţinute
Care au fost rezultatele obţinute în urma realizării proiectului vostru.
Concluzii
Download
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.
Jurnal
În această secțiune voi enumera problemele întâmpinate pe parcursul proiectului, dar și soluțiile găsite în cazul în care problema a fost rezolvată:
plăcuța nu mai accepta upload de cod din Platformio - la un moment dat, nu mai puteam da upload la codul din Platformio pe plăcuță, chiar dacă operațiunea de build era successful; problema este una recurentă în special pentru plăcuțele compatibile cu Arduino, dar neoriginale, iar soluția am găsit-o pe un forum dedicat Arduino, aceasta fiind apăsarea butonului de reset de pe plăcuță cât timp se execută primii pași din procesul de upload
matricea de LED-uri nu se aprindea - înainte de a apela la un ecran LCD penrtu afișare, am avut în plan să afișez heatmap-ul atât pe laptop, cât și pe o matrice de LED-uri conectată la plăcuță, dar din cauza faptului că această matrice, pentru a funcționa, avea nevoie de o bibliotecă din Python ce nu putea fi instalată (probabil pentru că nu era updatată de câțiva ani), nu am reușit să o fac să funcționeze
amplasarea motoarelor pe axele printate 3D - atât problema, cât și soluția au fost detaliate în partea de Hardware Design
contrastul ecranului LCD - ecranul LCD pe care l-am achiziționat are un șurub pe spate care reglează contrastul ecranului, iar acesta a fost livrat cu contrastul setat pe 0 (ecranul nu afișa nimic vizibil); soluția pentru reglarea ecranului și faptul că acesta, din fabrică, este setat pe are contratul setat pe 0 le-am aflat căutând datasheet-ul modelului de ecran
Bibliografie/Resurse