Inhoudsopgave:

Accel-schrijven (magische hand): 4 stappen (met afbeeldingen)
Accel-schrijven (magische hand): 4 stappen (met afbeeldingen)

Video: Accel-schrijven (magische hand): 4 stappen (met afbeeldingen)

Video: Accel-schrijven (magische hand): 4 stappen (met afbeeldingen)
Video: Dit ging niet zoals ik had verwacht..😳 2024, November
Anonim
Accel Schrijven (Magische Hand)
Accel Schrijven (Magische Hand)
Accel Schrijven (Magische Hand)
Accel Schrijven (Magische Hand)
Accel Schrijven (Magische Hand)
Accel Schrijven (Magische Hand)

Invoering

Met de magische hand kunnen mensen met een handicap en motorische stoornissen genieten van de creativiteit van tekenen en schrijven in een gesimuleerde omgeving. De Magic Hand is een draagbare handschoen die de beweging van je wijsvinger waarneemt en vertaalt naar het tekenen van lijnen op een computerscherm.

Benodigde materialen

LSM9DOF Breakout Board --- $24.95 ---

Adafruit Feather met Wifi --- $18.95 ---

Vrouwelijke/vrouwelijke draden --- $1.95 ---

Tape/klittenband --- $3

Twee magneten van gelijke sterkte --- Prijzen variëren

Hoe het werkt

Door een versnellingsmeter te gebruiken, kunnen we versnellingsgegevens verzamelen voor de y-as die ons zullen helpen bepalen wanneer de vinger van de gebruiker op en neer beweegt. Omdat onze versnellingsmeter versnelling meet ten opzichte van het middelpunt van de aarde, kunnen we de versnelling van de x-as (links of rechts) niet bepalen. Gelukkig bevat het LSM9DOF breakout board ook een magnetometer waarmee we gegevens over magnetische velden kunnen verzamelen. We plaatsen twee magneten 30 cm uit elkaar en hebben de handschoen ertussen. Als de magnetische gegevens positief zijn, weten we dat de handschoen naar rechts beweegt en vice versa. Nadat alle gegevens zijn verzameld in de versnellingsmeter/magnetometer, stuurt deze de gegevens via een draad naar de veer die is verbonden met een computer of wifi en stuurt de gegevens vervolgens door naar de computer die we vervolgens in onze code kunnen gebruiken.

Stap 1: Fysiek prototype 1

Fysiek prototype 1
Fysiek prototype 1
Fysiek prototype 1
Fysiek prototype 1

Dit prototype is bedoeld om met een handschoen losjes aan de hand te worden genaaid, zodat het over de elektronische apparaten kan glijden. Het elektronische apparaat wordt dan met klittenband aan de onderpantserhuls bevestigd in combinatie met een basishandschoen aan de hand. Dan glijdt de groene handschoen over de basis en de elektronische apparaten….

Stappen bij het maken van de prototypehandschoen:

  • Pak twee stukken stof die groot genoeg zijn om de hand te traceren
  • Trek de hand over beide stukken stof en knip ze uit
  • Plaats de twee handuitsparingen bij elkaar zodat ze perfect op één lijn liggen
  • Vervolgens, om de naaimachine voor te bereiden, voert u de draad door de aangegeven plekken op de machine
  • Wanneer de naaimachine is ingesteld, tilt u de naald op en plaatst u de twee in elkaar gestoken stukken stof onder de naald
  • Zorg ervoor dat de naald op de uiterste rand van de stof staat, start de machine en naai langs de randen van de stof, terwijl u de twee stukken aan de pols los laat zodat een hand erin past.

Stap 2: Fysiek prototype 2

Fysiek prototype 2
Fysiek prototype 2
Fysiek prototype 2
Fysiek prototype 2

Ons laatste prototype is een gewone handschoen gecombineerd met klittenband die aan elke pols verstelbaar is. De handschoen en riem zijn aan elkaar genaaid en de elektronische apparaten worden via klittenband aan de handschoen bevestigd.

Stappen bij het maken van het 2e prototype van de handschoen:

  1. Koop een handschoen, het materiaal van de handschoen maakt niet uit.
  2. Koop een polsbandje met klittenband
  3. Koop een draagbare batterij
  4. Koop kleverige klittenband
  5. Bevestig met een naainaald de polsband met klittenband aan de onderkant van de handschoen
  6. De polsband moet aan verschillende polsmaten kunnen worden aangepast.
  7. Bevestig de plakband aan de basis van de versnellingsmeter en bevestig deze aan de wijsvinger van de handschoen
  8. Bevestig plakband aan de veer en bevestig deze aan de bovenkant van de handschoen.
  9. Verbind de 3V3-pin in de veer met behulp van draden met de VIN-pin in de versnellingsmeter
  10. Verbind de GND-pin in de veer met behulp van draden met de GND-pin van de accelerometer.
  11. Verbind de SCL-pin in de veer met behulp van draden met de SCL-pin van de accelerometer.
  12. Verbind de SDA-pin in de veer met behulp van draden met de SDA-pin van de accelerometer.
  13. Sluit minimaal een 5 volt batterij via usb aan op de veer om stroom te leveren.

Stap 3: Magneten

Magneten
Magneten

Stap 1: Plaats de twee magneten van gelijke sterkte tegenover elkaar.

Stap 2: Meet de afstand van 30 cm tussen de twee magneten

Stap 3: plaats de Magnetometer precies in het midden van de twee magneten. U zou gegevens rond de 0 moeten ontvangen terwijl deze zich in het midden bevinden. Als u een nulwaarde krijgt, gaat u verder met stap 5.

Stap 4: Als de aflezing niet nul of dicht bij nul is, moet u de afstand van de magneten aanpassen. Als de aflezing negatief is, verplaats de linkermagneet dan een cm of 2 naar links of totdat de aflezing nul is. Als het positief is, doe dan hetzelfde, behalve met de juiste magneet.

Stap 5: Schrijf code die de gegevens van de magnetometer accepteert en leest of deze positief of negatief is. Als het positief is, laat de code dan een lijn naar rechts trekken en als het negatief is, trek dan een lijn naar links.

Stap 4: Coderen

Code
Code

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

Invoering:

Om gegevens van de accelerometer te kunnen verwerken, moet er een client/server-relatie tot stand worden gebracht tussen de Adafruit-veer en de server die de gegevens verwerkt (draaiend op een laptop/desktop). Er moeten twee codebestanden worden gemaakt: een voor de client (de Adafruit-veer) en de andere voor de server (in dit geval de laptop van Jarod). De client is geschreven in C++ en de server is geschreven in python. De taal die voor de client wordt gebruikt, is van belang, aangezien Arduino voornamelijk een C++-taal is, en het veranderen ervan om een andere taal te gebruiken is moeilijk. De server kan in elke taal worden geschreven, zolang deze maar netwerkfuncties heeft.

De klant instellen:

Eerst stellen we de klantcode in. De meeste wifi-verbindingscodes zijn direct beschikbaar via de Adafruit-bibliotheken. We beginnen met het opnemen van relevante lessen.

#include #include #include #include #include

Stel een aantal variabelen in die in de code zullen worden gebruikt.

// Maak verbinding met een netwerk const char* ssid = "MMServer"; const char* wachtwoord = "MMServer-wachtwoord"; // IP en poort van de server die data zal ontvangen const char* host = "149.160.251.3"; const int poort = 12347; bool verbonden = false;

// Bewegingsdetector initialiseren

Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0(1000);

WiFiClient-client;

Maak een setup()-functie die wordt uitgevoerd zodra de veer begint.

// Stel wifi-verbinding in en maak verbinding met de servervoid setup () { Serial.begin (9600); vertraging (100);

Serieel.println();

Serieel.println(); Serial.print("Verbinding maken met "); Seriële.println(ssid); // Start WiFi WiFi.begin (ssid, wachtwoord); // Verbinden… while (WiFi.status() != WL_CONNECTED) { delay(500); Serieel.print("."); } // Succesvol verbonden met WiFi Serial.println(""); Serial.println("WiFi verbonden"); Serial.println("IP-adres: "); Serial.println(WiFi.localIP());

#ifndef ESP8266

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

// Initialiseer de sensor

if(!lsm.begin()) { // Er is een probleem opgetreden bij het detecteren van de LSM9DS0 Serial.print(F("Ooops, geen LSM9DS0 gedetecteerd … Controleer uw bedrading of I2C-ADDR!")); terwijl(1); } Serial.println(F("Gevonden LSM9DS0 9DOF")); // Begin verbinding te maken met server Serial.print ("Verbinding maken met "); Serieel.println(host);

// Controleer op succesvolle verbinding. Indien mislukt, dan afbreken

if (!client.connect(host, poort)) { Serial.println("verbinding mislukt"); verbonden = onwaar; opbrengst; } else { verbonden = waar; }

// Stel de sensorversterking en integratietijd in

configureSensor(); }

We hebben dan een lusfunctie nodig die herhaaldelijk een lus maakt. In dit geval wordt het gebruikt om herhaaldelijk gegevens van de versnellingsmeter naar de server te verzenden in de vorm van "[z_accel]:[y_mag]:[z_mag]". De client.print(nummers); functie is wat gegevens naar de server stuurt.

void loop () { vertraging (250); if (connected) { // Dit stuurt gegevens naar de server sensors_event_t accel, mag, gyro, temp; lsm.getEvent(&accel, &mag, &gyro, &temp); String nummers; cijfers += accel.acceleration.z; cijfers += ":"; getallen += mag.magnetisch.y; cijfers += ":"; getallen += mag.magnetisch.z; Serieafdruk(cijfers); klant.print(nummers); Serieel.println(); } else { maak verbinding(); } }

Voor sommige hulpprogramma's hebben we er een nodig om de verbinding tussen de veer en de server tot stand te brengen.

void establishmentConnection(){ if (!client.connect(host, port)) { Serial.println("verbinding mislukt"); verbonden = onwaar; opbrengst; } else { verbonden = waar; } }

We moeten ook de sensor configureren en het waardenbereik geven dat het zal lezen. Acceleratie heeft bijvoorbeeld 5 opties voor het bereik: 2g, 4g, 6g, 8g en 16g.

void configureSensor (void) { // Stel het versnellingsmeterbereik in //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); // Stel de gevoeligheid van de magnetometer in //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_2GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_4GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_8GAUSS); lsm.setupMag(lsm. LSM9DS0_MAGGAIN_12GAUSS);

// Stel de gyroscoop in

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

De server instellen:

De server is een python-bestand dat op de opdrachtregel van een computer wordt uitgevoerd. Importeer om te beginnen de vereiste klassen.

import socketimport opnieuw import pyautogui

socket wordt gebruikt voor netwerken. re wordt gebruikt voor regex- of tekenreeksmanipulaties. pyautogui is een python-bibliotheek waarmee het tekenen kan gebeuren (later besproken).

Vervolgens moeten we enkele variabelen definiëren. Dit zullen globale variabelen zijn, dus ze zullen toegankelijk zijn in meerdere functies. Ze worden later in de code gebruikt.

i = 0n = 0 lijn = 1

data_list =

mag_data =

mag_calib_y = 0 mag_offset_y = 0

z_calib = 0

z_offset = 0 z_moving_offset = 0 z_diff = 0 z_real = 0 z_velo = 0 z_pos = 0

keep_offset = Onwaar

first_data = True

We hebben nu een functie nodig om een server te maken en deze te openen voor inkomende verbindingen.

def startServer(): global i global first_data # initialiseren server socket serversocket = socket.socket(socket. AF_INET, socket. SOCK_STREAM) serversocket.setsockopt(socket. SOL_SOCKET, socket. SO_REUSEADDR, 1) # Server IP-adres en poort host = " 149.160.251.3" port = 12347 server_address = (host, poort) # Open de server en luister naar inkomende verbindingen print ('Starting server on %s port %s' % server_address) serversocket.bind(server_address) serversocket.listen(5) # Wacht op verbindingen… while True: print ('Wachten op verbinding…') # Accepteer een inkomende verbinding (clientsocket, adres) = serversocket.accept() # Probeer de ontvangen gegevens te ontleden try: print ('Verbinding tot stand gebracht vanaf', adres) while True: # Ontvang de gegevens en verzend deze voor verwerking van gegevens = clientsocket.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: movingAcce l(accel_data[0]) processData(accel_data) first_data = False eindelijk: # Sluit de socket om onnodig datalek clientsocket.close() te voorkomen

We hebben nu de functies nodig die alle gegevens zullen verwerken. De eerste stap die moet worden genomen, en de eerste functie die wordt genoemd, is de kalibratie van de sensor voor de berekeningsdoeleinden.

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)

Vervolgens maken we een bewegende versnellingsoffset. Dit zorgt ervoor dat het programma herkent wanneer iemand stopt met het bewegen van zijn vinger, omdat alle waarden voor versnelling die naar de server worden gestuurd op dat moment hetzelfde moeten zijn.

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 of z_diff < -0.2): # beweging gedetecteerd binnen data, herstart keep_offset = True n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = break if not keep_offset: # stationair in data, set new z_offset z_offset = z_moving_offset print("Nieuwe z_offset: ") print(z_offset) n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = keep_offset = Onwaar keep_offset = Onwaar

Vervolgens doen we de dupe van de wiskunde. Dit houdt in dat de versnellingsgegevens worden vertaald naar positiegegevens waarmee we de richting kunnen bepalen waarin de gebruiker zijn vinger beweegt.

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(lijst[0]) - z_offset

mag_y = lijst[1] mag_z = lijst[2] left = False right = False # Verwerk de acceleratie pas als het absoluut zeker is dat deze is versneld # Voorkomt dat mechanische ruis bijdraagt aan de positie if(z_real -0.20): z_real = 0 #Begin integraties om positie te vinden 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(links): beweging(-50, int(z_pos*1000)) z_velo = 0 z_pos = 0

Nu, eindelijk, verplaatsen we de cursor! Om dit te doen, hebben we een verfvenster geopend en het schermvullend gemaakt. De pyautogui-bibliotheek bevat een functie genaamd pyautogui.dragRel(x, y); die we gebruiken om de muiscursor van het ene punt naar het andere te slepen. Het gebruikt relatieve positiegegevens, zodat de beweging relatief is ten opzichte van de laatste positie van de cursor.

def beweging(x, y): print("verplaatsen naar", x, -y) pyautogui.dragRel(x, -y)

Ten slotte moeten we de hoofdfunctie aanroepen om zelfs al deze code te laten uitvoeren.

# Roept de functie aan om de serverstartServer() te starten

Aanbevolen: