MouseXYZ foloseste un accelerometru pentru a transmite informatii despre miscarea sa in spatiul 3D sub forma unor pachete de mouse USB.
El se poate lega la orice calculator care suporta mouse USB si poate fi folosit pe post de mouse obisnuit (cu mousewheel).
O aplicatie mai interesanta este head tracking - folosind un exemplu simplu Direct3D9, camera este miscata in jurul unui cub in functie de datele trimise de mouse. Daca mouse-ul urmareste miscarile capului privitorului, se va crea pentru acesta un efect de tridimensionalitate.
Componente adugate la partea doua a proiectului:
Componenta | Numar | Magazin |
---|---|---|
condensator 0.1μF | 4 | Conex electronic |
accelerometru MMA7260QT | 1 | TME, Farnell(nu se mai gaseste) |
rezistenta 100Ω | 3 | Conex electronic |
condensator 470μF | 1 | Conex electronic |
stabilizator tensiune 3.3V LF33 | 1 | Conex electronic |
Pret total | ~10RON + 10EUR accelerometru |
Programul de pe microcontroller porneste de la exemplul HID-mouse pus la dispozitie alaturi de driverul USB VUSB. Programul foloseste Timer1 pentru a citi la 20 ms acceleratiile pe cele trei axe. Cu acestea se calculeaza viteza pe fiecare axa. Vitezele pe x si pe y sunt tranmise ca deplasamentul pe x si y din pachetul de mouse USB. Viteza pe z este transmisa ca deplasamentul mouse wheel-ului din acel pachet. Am realizat pogramul in WinAVR, folosinf PonyProg pentru a-l transfera pe microcontroller.
Partea de actualizare a vitezei (se apeleaza la fiecare 10 ms, folosind Timer 1):
x = ADC_get (CX);//citeste prin ADC (vezi lab 2) acceleratia pe X y = ADC_get (CY);//acceleratia pe y z = ADC_get (CZ);//acceleratia pe z x -= x0;//x0 este valoarea citita cand acceleratia ar trebui sa fie 0 (0g -> x0 ; cati g -> x : x - x0) //in mod normal, x0 este 40 y -= y0;//y0 este deobicei cam 40 z -= z0;//z0 este deobicei 70 (pe z am acceleratia gravitationala) if (abs (x + v.x) < 127) v.x += x;//ma asigur ca nu voi avea depasire la viteza (pe 8 biti cu semn => val maxima este 127): //daca adaugand acceleratia asta la viteza as depasi ±127, valoarea nu se schimba if (abs (y + v.y) < 127) v.y += y; if (abs (z + v.z) < 127) v.z += z;
Partea de transmitere prin USB a informatiilor (in bucla principala din main() ):
//report buffer este o structura predefinita, care contine 4 bytes trimisi pe USB: butoanele apasate(nu am folosit), deplasarea pe X, deplasarea pe Y //si deplasarea rotitei reportBuffer.dx = abs(v.x/10) > 5 ? v.x/10 : 0;//consider ca deplasarea este viteza calculata/10, dar daca rezultatul este mai mic decat 5, //probabil este doar zgomot,trimit 0; totusi, nu fac viteza 0 pentru a permite cresterea //vitezei cu acceleratii mici reportBuffer.dy = abs(v.y/10) > 5 ? v.y/10 : 0; reportBuffer.dWheel = abs(v.z/10) > 5 ? v.z/10 : 0;//transmit coordonata Z sub forma rotitei de mouse => nu am nevoie de nici un driver //special pe calculator pentru functionarea mouseului, daca folosesc intr-un //program toate cele trei coordonate, voi folosi si indicatiile despre mouse wheel //date de sistemul de operare. //pentru calibrare se poate umbla la valoarea cu care este impartita viteza (/10) si la limita considerata zgomot ( >5 )
Exemplul pentru head tracking foloseste Direct3D pentru a desena un cub si a misca camera in funtie de pozitia mouseului. Programul este realizat in VisualSTudio 2010, folosind si DirectXSDK.
MouseXYZ poate functiona ca mouse, dar are un lag datorat impreciziilor citirilor de acceleratii, marite de calculele facute cu acestea.
Screenshot din exemplul(foarte simplu) pentru head tracking:
E probabil nevoie de mai mult timp pentru calibrarea corecta a valorilor adaugate vitezei citindo o anumita acceleratie pentru a se obtine un control real.
Sursele si .hex pentru programul de pe microcontroller:
Sursa si executabil pentru exemplul de head tracking (compilat pe Windows7, pentru compilarea surselor este nevoie si de DirectXSDK):
Datasheet-ul accelerometrului MMA7260QT: http://www.freescale.com/files/sensors/doc/data_sheet/MMA7260QT.pdf
Datasheet-ul procesorului AtMega16: http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf
Driverul de USB VUSB: http://www.obdev.at/products/vusb/download.html
DirectX Tutorial, de unde am luat majoritatea codului pentru exemplul de headtracking: http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B9.aspx
Un proiect asemanator, pe care l-am folosit pentru ideea despre cum se calibreaza datele citite: http://www.uchobby.com/index.php/2007/10/27/accelerometer-based-mouse/