Spisu treści:

Accel Writing (Magiczna ręka): 4 kroki (ze zdjęciami)
Accel Writing (Magiczna ręka): 4 kroki (ze zdjęciami)

Wideo: Accel Writing (Magiczna ręka): 4 kroki (ze zdjęciami)

Wideo: Accel Writing (Magiczna ręka): 4 kroki (ze zdjęciami)
Wideo: Jak zwiększyć swoją produktywność 2024, Listopad
Anonim
Przyspieszone pisanie (magiczna ręka)
Przyspieszone pisanie (magiczna ręka)
Przyspieszone pisanie (magiczna ręka)
Przyspieszone pisanie (magiczna ręka)
Przyspieszone pisanie (magiczna ręka)
Przyspieszone pisanie (magiczna ręka)

Wstęp

Magiczna ręka pozwala osobom niepełnosprawnym i upośledzonym ruchowo cieszyć się kreatywnością rysowania i pisania w symulowanym środowisku. Magiczna Dłoń to rękawica do noszenia, która wyczuwa ruch palca wskazującego i przekłada to na rysowanie linii na ekranie komputera.

Potrzebne materiały

LSM9DOF Breakout Board --- 24,95 USD ---

Piórko Adafruit z Wi-Fi --- 18,95 USD ---

Przewody żeńskie/żeńskie --- 1,95 USD ---

Taśmy / paski na rzep --- 3 USD

Dwa magnesy o równej sile --- Ceny różnią się

Jak to działa

Za pomocą akcelerometru możemy zebrać dane dotyczące przyspieszenia osi y, które pomogą nam określić, kiedy palec użytkownika porusza się w górę iw dół. Ze względu na to, że nasz akcelerometr mierzy przyspieszenie względem środka Ziemi, nie możemy określić przyspieszenia osi x (lewej lub prawej). Na szczęście tabliczka zaciskowa LSM9DOF zawiera również magnetometr, który pozwala nam zbierać dane o polach magnetycznych. Umieszczamy dwa magnesy w odległości 30 cm i między nimi mamy rękawicę. Jeśli dane magnetyczne są dodatnie, wiemy, że rękawica porusza się w prawo i odwrotnie. Po zebraniu wszystkich danych w akcelerometrze/magnetometrze, przesyła on dane przewodem do pióra, które jest podłączone do komputera Wi-Fi, a następnie przesyła dane do komputera, który możemy następnie wykorzystać w naszym kodzie.

Krok 1: Fizyczny prototyp 1

Fizyczny prototyp 1
Fizyczny prototyp 1
Fizyczny prototyp 1
Fizyczny prototyp 1

Ten prototyp ma być zszytymi luźno rękawiczkami na dłoni, aby mógł nasunąć się na urządzenia elektroniczne. Urządzenie elektroniczne zostanie następnie przymocowane rzepem do podstawy rękawa pod zbroją w połączeniu z podstawową rękawicą na dłoni. Wtedy zielona rękawiczka ześlizgnie się na podstawę i urządzenia elektroniczne….

Etapy wykonania prototypu rękawicy:

  • Zdobądź dwa kawałki materiału wystarczająco duże, aby prześledzić rękę
  • Narysuj dłoń na obu kawałkach materiału i wytnij je
  • Połącz dwa wycięcia na dłonie, aby były idealnie dopasowane
  • Następnie, aby przygotować maszynę do szycia, przeciągnij nić przez wskazane miejsca na maszynie
  • Po ustawieniu maszyny do szycia podnieś igłę i umieść dwa połączone kawałki materiału pod igłą
  • Upewnij się, że igła jest wyrównana na samym brzegu materiału, uruchom maszynę i zszyj wzdłuż brzegów materiału, pozostawiając dwie części nie zszyte na nadgarstku, aby ręka mogła się zmieścić.

Krok 2: Fizyczny prototyp 2

Fizyczny prototyp 2
Fizyczny prototyp 2
Fizyczny prototyp 2
Fizyczny prototyp 2

Nasz ostateczny prototyp to zwykła rękawica połączona z paskiem na rzep, który można dopasować do każdego nadgarstka. Rękawica i pasek są zszyte, a urządzenia elektroniczne przymocowane do rękawicy za pomocą rzepa.

Etapy wykonania drugiego prototypu rękawicy:

  1. Kup rękawicę, materiał rękawicy nie ma znaczenia.
  2. Kup pasek na nadgarstek z rzepem
  3. Kup przenośną baterię
  4. Kup Sticky Velcro
  5. Za pomocą igły do szycia przymocuj pasek na nadgarstek z rzepem do podstawy rękawicy
  6. Pasek na nadgarstek powinien być w stanie dopasować się do różnych rozmiarów nadgarstka.
  7. Przymocuj taśmę klejącą do podstawy akcelerometru i przymocuj ją do palca wskazującego rękawicy
  8. Przyklej taśmę klejącą do pióra i przymocuj ją do górnej części rękawicy.
  9. Za pomocą przewodów połącz pin 3V3 w piórku z pinem VIN w akcelerometrze
  10. Za pomocą przewodów połącz pin GND w piórku z pinem GND akcelerometru.
  11. Za pomocą przewodów połącz pin SCL w piórku z pinem SCL akcelerometru.
  12. Za pomocą przewodów połącz pin SDA w piórze z pinem SDA akcelerometru.
  13. Podłącz co najmniej 5-woltową baterię przez USB do pióra, aby zapewnić zasilanie.

Krok 3: Magnesy

Magnesy
Magnesy

Krok 1: Umieść dwa magnesy o jednakowej sile naprzeciwko siebie.

Krok 2: Odmierz 30 cm odstępu między dwoma magnesami

Krok 3: umieść magnetometr dokładnie pośrodku dwóch magnesów. Powinieneś otrzymać dane około 0, gdy jest w środku. Jeśli otrzymasz odczyt równy zero, przejdź do kroku 5.

Krok 4: Jeśli odczyt nie jest zerowy lub bliski zera, musisz dostosować odległość magnesów. Jeśli odczyt jest ujemny, przesuń lewy magnes o cm lub 2 w lewo lub aż odczyt wyniesie zero. Jeśli jest pozytywny, zrób to samo, z wyjątkiem właściwego magnesu.

Krok 5: Napisz kod, który akceptuje dane z magnetometru i odczytuje, czy jest dodatni, czy ujemny. Jeśli kod jest dodatni, narysuj linię w prawo, a jeśli ujemny, narysuj linię w lewo.

Krok 4: Kod

Kod
Kod

github.iu.edu/ise-e101-F17/MuscleMemory-Sw…

Wstęp:

Aby przetworzyć dane z akcelerometru, należy ustanowić relację klient/serwer pomiędzy piórkiem Adafruit a serwerem przetwarzającym dane (działającym na laptopie/komputerze). Trzeba będzie stworzyć dwa pliki kodu: jeden dla klienta (piórko Adafruit), a drugi dla serwera (w tym przypadku laptopa Jaroda). Klient jest napisany w C++, a serwer w Pythonie. Język używany dla klienta ma znaczenie, ponieważ Arduino to głównie język C++, a zmiana go na inny język jest trudna. Serwer może być napisany w dowolnym języku, o ile posiada funkcje sieciowe.

Konfiguracja Klienta:

Najpierw skonfigurujemy kod klienta. Większość kodu połączenia Wi-Fi jest łatwo dostępna za pośrednictwem bibliotek Adafruit. Zaczynamy od włączenia odpowiednich klas.

#include #include #include #include #include

Ustaw kilka zmiennych, które będą używane w całym kodzie.

// Połącz się z siecią const char* ssid = "MMServer"; const char* hasło = "MMServer-Password"; // IP i port serwera, który otrzyma dane const char* host = "149.160.251.3"; const int port = 12347; bool podłączony = fałsz;

// Zainicjuj detektor ruchu

Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0(1000);

Klient WiFiClient;

Utwórz funkcję setup(), która zostanie uruchomiona, gdy tylko zacznie się wtapianie.

// Skonfiguruj połączenie WiFi i połącz się z serwerem. setup() { Serial.begin(9600); opóźnienie (100);

Serial.println();

Serial.println(); Serial.print("Łączenie z"); Serial.println(ssid); // Uruchom WiFi WiFi.begin(ssid, hasło); // Łączenie… while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Pomyślnie połączono z WiFi Serial.println(""); Serial.println("Połączenie WiFi"); Serial.println("adres IP: "); Serial.println(WiFi.localIP());

#ifndef ESP8266

while(!Serial); #endif Serial.begin(9600); Serial.println("Test czujnika");

// Zainicjuj czujnik

if(!lsm.begin()) { // Wystąpił problem z wykryciem LSM9DS0 Serial.print(F("Ups, nie wykryto LSM9DS0… Sprawdź okablowanie lub I2C ADDR!")); natomiast(1); } Serial.println(F("Znaleziono LSM9DS0 9DOF")); // Rozpocznij połączenie z serwerem Serial.print("Łączenie z "); Serial.println(host);

// Sprawdź pomyślne połączenie. Jeśli się nie powiedzie, przerwij

if (!client.connect(host, port)) { Serial.println("połączenie nie powiodło się"); połączony = fałsz; powrót; } else { połączony = prawda; }

//Ustaw wzmocnienie czujnika i czas integracji

configureSensor(); }

Następnie potrzebujemy funkcji pętli, która będzie wielokrotnie zapętlać. W tym przypadku służy do wielokrotnego przesyłania danych z akcelerometru na serwer w postaci „[z_accel]:[y_mag]:[z_mag]”. Klient.print(liczby); funkcja jest tym, co wysyła dane do serwera.

void loop() { opóźnienie(250); if(connected){ // Spowoduje to wysłanie danych do serwera sensor_event_t accel, mag, gyro, temp; lsm.getEvent(&akceleracja, &mag, &żyroskop, &temp); Numery ciągów; liczby += akceleracja.przyspieszenie.z; liczby += ":"; liczby += mag.magnetyczny.y; liczby += ":"; liczby += mag.magnetyczny.z; Serial.print(liczby); klient.print(liczby); Serial.println(); } else { ustanawianiePołączenia(); } }

W przypadku niektórych funkcji narzędziowych potrzebujemy go do ustanowienia połączenia między piórem a serwerem.

void EstablishConnection(){ if (!client.connect(host, port)) { Serial.println("połączenie nie powiodło się"); połączony = fałsz; powrót; } else { połączony = prawda; } }

Musimy również skonfigurować czujnik i podać mu zakres wartości, które będzie odczytywał. Na przykład przyspieszenie ma 5 opcji dla zakresu: 2g, 4g, 6g, 8g i 16g.

void configureSensor(void){ // Ustaw zakres akcelerometru //lsm.setupAccel(lsm. LSM9DS0_ACCELRANGE_2G); lsm.setupAccel(lsm. LSM9DS0_ACCELRANGE_4G); //lsm.setupAccel(lsm. LSM9DS0_ACCELRANGE_6G); //lsm.setupAccel(lsm. LSM9DS0_ACCELRANGE_8G); //lsm.setupAccel(lsm. LSM9DS0_ACCELRANGE_16G); // Ustaw czułość magnetometru //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_2GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_4GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_8GAUSS); lsm.setupMag(lsm. LSM9DS0_MAGGAIN_12GAUSS);

// Skonfiguruj żyroskop

lsm.setupGyro(lsm. LSM9DS0_GYROSCALE_245DPS); //lsm.setupGyro(lsm. LSM9DS0_GYROSCALE_500DPS); //lsm.setupGyro(lsm. LSM9DS0_GYROSCALE_2000DPS); }

Konfiguracja serwera:

Serwer będzie plikiem Pythona, który będzie działał w wierszu poleceń komputera. Aby rozpocząć, zaimportuj wymagane klasy.

import socketimport ponownie import pyautogui

gniazdo jest używane do pracy w sieci. re jest używany do manipulacji wyrażeniami regularnymi lub łańcuchami. pyautogui to biblioteka Pythona, która pozwoli na rysowanie (omówione później).

Następnie powinniśmy zdefiniować kilka zmiennych. Będą to zmienne globalne, więc będą dostępne w wielu funkcjach. Zostaną użyte w dalszej części kodu.

i = 0n = 0 linia = 1

lista_danych =

mag_dane =

mag_calib_y = 0 mag_offset_y = 0

z_kalib = 0

z_przesunięcie = 0 z_przesunięcie_ruchu = 0 z_różnica = 0 z_rzeczywista = 0 z_velo = 0 z_poz = 0

zachowaj_przesunięcie = Fałsz

pierwsze_dane = Prawda

Potrzebujemy teraz funkcji do tworzenia serwera i otwierania go dla połączeń przychodzących.

def startServer(): globalne i globalne pierwsze_dane # zainicjuj gniazdo serwera serverocket = socket.socket(socket. AF_INET, socket. SOCK_STREAM) serverocket.setsockopt(socket. SOL_SOCKET, socket. SO_REUSEADDR, 1) # Adres IP serwera i host portu = " 149.160.251.3" port = 12347 adres_serwera = (host, port) # Otwórz serwer i nasłuchuj połączeń przychodzących print ('Uruchamianie serwera na porcie %s %s' % adres_serwera) serverocket.bind(adres_serwera) serverocket.listen(5) # Czekaj na połączenia… while True: print ('Oczekiwanie na połączenie…') # Zaakceptuj połączenie przychodzące (clientsocket, adres) = serverocket.accept() # Spróbuj przeanalizować otrzymane dane try: print ('Połączenie ustanowione z ', adres) while True: # Odbierz dane i wyślij je do przetwarzania dane = customersocket.recv(25) accel_data = re.split('[:]', str(data)) accel_data[0] = accel_data[0][2:] accel_data[1] = accel_data[1] accel_data[2] = accel_data[2][1:-1] print(accel_data) i+=1 if(i < 51): calibData(accel_data) else: moveAcce l(accel_data[0]) processData(accel_data) first_data = False w końcu: # Zamknij gniazdo, aby zapobiec niepotrzebnemu wyciekowi danych customersocket.close()

Teraz potrzebujemy funkcji, które będą przetwarzać wszystkie dane. Pierwszym krokiem, który należy wykonać i pierwszą wywołaną funkcją, jest kalibracja czujnika do celów obliczeniowych.

def calibData(list): global z_calib global z_offset global mag_data global mag_calib_y global mag_offset_y z_calib += float(list[0]) mag_calib_y += float(list[1]) if(i==50): z_offset = z_calib / 50 mag_offset_y = mag_calib_y / 50 z_calib = 0 mag_calib_y = 0 mag_data.append(mag_offset_y)

Następnie tworzymy przesunięcie przyspieszenia ruchu. Dzięki temu program rozpoznaje, kiedy ktoś przestaje poruszać palcem, ponieważ wszystkie wartości przyspieszenia wysyłane do serwera powinny być w tym czasie takie same.

def movingAccel(num): global z_calib global z_diff global z_moving_offset global z_offset global data_list global n global keep_offset if(n 0.2 lub z_diff < -0.2): # ruch wykryty w danych, uruchom ponownie keep_offset = True n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = przerwa, jeśli nie zachowaj_przesunięcie: # nieruchome w danych, ustaw nowe z_offset z_offset = z_moving_offset print("Nowe z_offset: ") print(z_offset) n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = keep_offset = False keep_offset = False

Następnie robimy główny ciężar matematyki. Wiąże się to z przetłumaczeniem danych przyspieszenia na dane pozycji, które pozwolą nam określić kierunek, w którym użytkownik porusza palcem.

def processData(list): #[accel.z, mag.y] global z_offset global z_real global z_velo global z_pos global first_data global mag_data

z_real = float(list[0]) - z_offset

mag_y = lista[1] mag_z = lista[2] left = False right = False # Nie przetwarzaj przyspieszenia, dopóki nie jest absolutnie pewien, że przyspieszyło # Zapobiega wpływowi hałasu mechanicznego na pozycję if(z_real -0.20): z_real = 0 #Begin integracje do znalezienia pozycji if(first_data): mag_data.append(mag_y) z_pos = (0.5 * z_real * 0.25 * 0.25) + (z_velo * 0.25) + z_pos z_velo = z_real * 0.25 pyautogui.moveTo(1500, 1000) else: z_pos = (0.5 * z_real * 0.25 * 0.25) + (z_velo * 0.25) + z_pos z_velo = (z_real * 0.25) + z_velo del mag_data[0] mag_data.append(mag_y) if(float(mag_data[1]) - float(mag_data[0]) > 0.03): right = True elif(float(mag_data[1]) - float(mag_data[0]) < -0.03): left = True if(right): movement(50, int(z_pos* 1000)) elif(po lewej): ruch(-50, int(z_pos*1000)) z_velo = 0 z_pos = 0

Teraz wreszcie przesuwamy kursor! Aby to zrobić, otworzyliśmy okno farby i ustawiliśmy je na pełnym ekranie. Biblioteka pyautogui zawiera funkcję o nazwie pyautogui.dragRel(x, y); którego używamy do przeciągania kursora myszy z jednego punktu do następnego. Wykorzystuje dane pozycji względnej, więc ruch jest względny do ostatniej pozycji kursora.

def ruch(x, y): print("przejście do", x, -y) pyautogui.dragRel(x, -y)

Na koniec musimy wywołać funkcję main, aby nawet umożliwić uruchomienie całego tego kodu.

# Wywołuje funkcję, aby rozpocząć serverstartServer()

Zalecana: