Śledzenie położenia dłoni Arduino

Śledzenie położenia dłoni Arduino

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:

  1. 3 tekturowe kwadraty o przekątnej 12″ (ok. 30cm)
  2. folia aluminiowa
  3. 3 krokodylki
  4. rezystory 3x 10k, 3x 220k
  5. Arduino Uno
  6. 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.

Q5n5SHpAdesUAVEF

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.

vnMhkLZVqZmA2rQG

Poniższe zdjęcie pokazuje gotowe połączenie.

pSoriEaQZPtyagcs

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 :(

Ocena: 1/5 (głosów: 5)

Podobne posty

5 komentarzy do “Śledzenie położenia dłoni Arduino

Odpowiedz

anuluj

Masz uwagi?