INFORMACJA: Poniższy post nie wydostał się z Poczekalni :(
Witam serdecznie wszystkich czytelników.
Jest to mój pierwszy wpis na Majsterkowo.pl. W dzisiejszym artykule pragnę przedstawić projekt oparty na Arduino, w którym będzie wykrywany ruch i położenie naszej dłoni. Pozycja ręki będzie pokazywana w oknie Processing-u. Projekt może nie jest pożyteczny, ale może przynieść dużo zabawy.
Zabieramy się więc do pracy.
Co nam będzie potrzebne:
- 3 tekturowe kwadraty o przekątnej 12″ (ok. 30cm)
- folia aluminiowa
- 3 krokodylki
- rezystory 3x 10k, 3x 220k
- Arduino Uno
- kabel koncentryczny
Na tekturowe kwadraty starannie naklej folię aluminiową zostawiając ok. 2 cm marginesu. Następnie je sklej tak aby tworzyły niezamknięty sześcian. Musimy jednak pamiętać aby boki kwadratów były połączone pod kątem 90*i poszczególne kawałki folii nie były złączone ze sobą.
Następnie musimy przygotować okablowanie. Ważne jest to aby był użyty kabel koncentryczny, który zlikwiduje jakiekolwiek zakłócenia, które mogłyby pogorszyć odczyt. Podziel kabel na trzy kawałki równej długości. Później ściągnij izolację z oplotu i przewodu sygnałowego. Przewód sygnałowy połącz z krokodylkiem, który przyłącz do folii. Pamiętaj aby odizolować oplot od sygnału.
Po drugiej stronie kabla złącz ze sobą oploty, które będą podłączone pod 5V na Arduino. Za pomocą rezystorów 220k połącz 5V z przewodami sygnałowymi, które są podpięte rezystorami 10k do pinów (8,9,10) w Arduino.
Poniższe zdjęcie pokazuje gotowe połączenie.
Klipsy powinny być podpięte w następującej kolejności:
pin 8 = lewa płytka ( x) , pin 9 = dolna płyta ( y ) , pin 10 = prawa płytka ( z)
Upewnij się multimetrem czy krokodylki zostały dobrze podpięte do folii.
Program Arduino:
// Śledzenie dłoni za pomocą Arduino #define analiza 8 #define mains 50 #define odswiezenie 2 * 1000000 / mains void setup() { Serial.begin(115200); for(int i = 2; i < 14; i++) { pinMode(i, OUTPUT); digitalWrite(i, LOW); } for(int i = 8; i < 11; i++) pinMode(i, INPUT); startTimer(); } void loop() { Serial.print(time(8, B00000001), DEC); Serial.print(" "); Serial.print(time(9, B00000010), DEC); Serial.print(" "); Serial.println(time(10, B00000100), DEC); } long time(int pin, byte mask) { unsigned long count = 0, total = 0; while(checkTimer() < odswiezenie) { pinMode(pin, OUTPUT); PORTB = 0; pinMode(pin, INPUT); while((PINB & mask) == 0) count++; total++; } startTimer(); return (count << analiza) / total; } extern volatile unsigned long timer0_overflow_count; void startTimer() { timer0_overflow_count = 0; TCNT0 = 0; } unsigned long checkTimer() { return ((timer0_overflow_count << 8) + TCNT0) << 2; }
Program Processing:
// Śledzenie dłoni za pomocą Arduino import processing.serial.*; import processing.opengl.*; Serial serial; int serialPort = 1; // port pod który podłączone jest Arduino (COM1) int sen = 3; // sensor int div = 3; Normalize n[] = new Normalize[sen]; MomentumAverage cama[] = new MomentumAverage[sen]; MomentumAverage axyz[] = new MomentumAverage[sen]; float[] nxyz = new float[sen]; int[] ixyz = new int[sen]; float w = 256; boolean[] flip = { false, true, false}; int player = 0; boolean moves[][][][]; PFont font; void setup() { size(800, 600, OPENGL); frameRate(25); font = loadFont("TrebuchetMS-Italic-20.vlw"); textFont(font); textMode(SHAPE); println(Serial.list()); serial = new Serial(this, Serial.list()[serialPort], 115200); for(int i = 0; i < sen; i++) { n[i] = new Normalize(); cama[i] = new MomentumAverage(.01); axyz[i] = new MomentumAverage(.15); } reset(); } void draw() { updateSerial(); drawBoard(); } void updateSerial() { String cur = serial.readStringUntil('\n'); String[] parts = split(cur, " "); if(parts.length == sen ) { float[] xyz = new float[sen]; for(int i = 0; i < sen; i++) xyz[i] = float(parts[i]); if(mousePressed && mouseButton == LEFT) for(int i = 0; i < sen; i++) n[i].note(xyz[i]); nxyz = new float[sen]; for(int i = 0; i < sen; i++) { float raw = n[i].choose(xyz[i]); nxyz[i] = flip[i] ? 1 - raw : raw; cama[i].note(nxyz[i]); axyz[i].note(nxyz[i]); ixyz[i] = getPosition(axyz[i].avg); } } } } float cutoff = .2; int getPosition(float x) { if(div == 3) { if(x < cutoff) return 0; if(x < 1 - cutoff) return 1; else return 2; } else { return x == 1 ? div - 1 : (int) x * div; } } void drawBoard() { background(255); float h = w / 2; camera( h + (cama[0].avg - cama[2].avg) * h, h + (cama[1].avg - 1) * height / 2, w * 2, h, h, h, 0, 1, 0); pushMatrix(); noFill(); stroke(0, 40); translate(w/2, w/2, w/2); rotateY(-HALF_PI/2); box(w); popMatrix(); float sw = w / div; translate(h, sw / 2, 0); rotateY(-HALF_PI/2); pushMatrix(); float sd = sw * (div - 1); translate( axyz[0].avg * sd, axyz[1].avg * sd, axyz[2].avg * sd); fill(255, 160, 0, 200); noStroke(); sphere(18); popMatrix(); for(int z = 0; z < div; z++) { for(int y = 0; y < div; y++) { for(int x = 0; x < div; x++) { pushMatrix(); translate(x sw, y sw, z * sw); noStroke(); if(moves[0][x][y][z]) fill(255, 0, 0, 200); else if(moves[1][x][y][z]) fill(0, 0, 255, 200); else if( x == ixyz[0] && y == ixyz[1] && z == ixyz[2]) if(player == 0) fill(255, 0, 0, 200); else fill(0, 0, 255, 200); else fill(0, 100); box(sw / 3); popMatrix(); } } } stroke(0); if(mousePressed && mouseButton == LEFT) msg("defining boundaries"); } void keyPressed() { if(key == TAB) { moves[player][ixyz[0]][ixyz[1]][ixyz[2]] = true; player = player == 0 ? 1 : 0; } } void mousePressed() { if(mouseButton == RIGHT) reset(); } void reset() { moves = new boolean[2][div][div][div]; for(int i = 0; i < sen; i++) { n[i].reset(); cama[i].reset(); axyz[i].reset(); } } void msg(String msg) { println(msg); }
Kalibracja oprogramowania:
Po podłączeniu Arduino do komputera i wgraniu programów. Otwórz okno Processing-u i przytrzymaj lewy przycisk myszy, równocześnie przesuwając rękę po przekątnej do środka bryły nie dotykając folii. Po zwolnieniu przycisku program analizuje zakres ruchów.
INFORMACJA: Poniższy post nie wydostał się z Poczekalni :(
Brakuje mi jakiegoś filmu z prezentacją działania. I w ogóle mam wrażenie, że coś Ci ucięło ten artykuł (albo przypadkowo opublikowałeś go przez ukończeniem;)
Na razie nie oceniam.
Podpisuje się pod tym co napisał Kolega Barry.
Filmy z działania możecie znaleźć na innych stronach z tym projektem, na przykład tych:
http://makezine.com/projects/a-touchless-3d-tracking-interface/
http://www.instructables.com/id/DIY-3D-Controller/
Jak by tu powiedzieć…
https://makerspace.com/projects/a-touchless-3d-tracking-interface
ethanak: Punkt za czujność! Nawet nasz system antyplagiatowy nie zdążył tego jeszcze wyłapać ;)