Accel Writing (Magic Hand): 4 étapes (avec photos)
Accel Writing (Magic Hand): 4 étapes (avec photos)
Anonim
Écriture accélérée (main magique)
Écriture accélérée (main magique)
Écriture accélérée (main magique)
Écriture accélérée (main magique)
Écriture accélérée (main magique)
Écriture accélérée (main magique)

introduction

La main magique permet aux personnes handicapées et aux déficiences motrices de profiter de la créativité du dessin et de l'écriture dans un environnement simulé. Le Magic Hand est un gant portable qui détecte le mouvement de votre index et le traduit en dessin de lignes sur un écran d'ordinateur.

Les matériaux nécessaires

Carte de dérivation LSM9DOF --- 24,95 $ ---

Plume d'Adafruit avec Wifi --- 18,95 $ ---

Fils femelle/femelle --- $1.95 ---

Bandes adhésives/velcro --- 3 $

Deux aimants de force égale --- Les prix varient

Comment ça fonctionne

En utilisant un accéléromètre, nous pouvons collecter des données d'accélération pour l'axe y qui nous aideront à déterminer quand le doigt de l'utilisateur se déplace de haut en bas. En raison du fait que notre accéléromètre mesure l'accélération par rapport au centre de la terre, nous ne pouvons pas déterminer l'accélération de l'axe x (gauche ou droite). Heureusement, la carte de dérivation LSM9DOF contient également un magnétomètre qui nous permet de collecter des données sur les champs magnétiques. Nous plaçons deux aimants à 30 cm l'un de l'autre et avons le gant entre les deux. Si les données magnétiques sont positives, nous savons que le gant se déplace vers la droite et vice versa. Une fois que toutes les données sont collectées dans l'accéléromètre/magnétomètre, il envoie les données par fil à la plume qui est connectée à un ordinateur de wifi, puis transmet les données à l'ordinateur que nous pouvons ensuite utiliser dans notre code.

Étape 1: Prototype physique 1

Prototype physique 1
Prototype physique 1
Prototype physique 1
Prototype physique 1

Ce prototype est destiné à être cousu de manière lâche sur la main afin qu'il puisse glisser sur les appareils électroniques. Le dispositif électronique sera ensuite fixé par velcro à la base de la manche sous blindage associé à un gant basique à la main. Ensuite, le gant vert glissera sur la base et les appareils électroniques….

Étapes de fabrication du prototype de gant:

  • Obtenez deux morceaux de tissu assez grands pour tracer la main
  • Tracez la main sur les deux morceaux de tissu et découpez-les
  • Assemblez les deux découpes des mains pour qu'elles soient parfaitement alignées
  • Ensuite, pour préparer la machine à coudre, faites passer le fil par les endroits indiqués sur la machine
  • Lorsque la machine à coudre est installée, soulevez l'aiguille et placez les deux morceaux de tissu assemblés sous l'aiguille
  • Assurez-vous que l'aiguille est alignée sur le bord même du tissu, démarrez la machine et cousez le long des bords du tissu, tout en laissant les deux pièces non cousues au niveau du poignet pour qu'une main puisse entrer.

Étape 2: Prototype physique 2

Prototype physique 2
Prototype physique 2
Prototype physique 2
Prototype physique 2

Notre prototype final est un gant régulier combiné à une bande Velcro qui s'adapte à n'importe quel poignet. Le gant et la sangle sont cousus ensemble, et les appareils électroniques sont attachés au gant par velcro.

Etapes de fabrication du 2ème prototype du gant:

  1. Achetez un gant, le matériau du gant n'a pas d'importance.
  2. Achetez une dragonne velcro
  3. Acheter une batterie portable
  4. Acheter du velcro collant
  5. Avec une aiguille à coudre, attachez la dragonne velcro à la base du gant
  6. La dragonne doit pouvoir s'adapter à différentes tailles de poignet.
  7. Fixez le ruban adhésif à la base de l'accéléromètre et fixez-le à l'index du gant
  8. Attachez du ruban adhésif à la plume et fixez-le sur le dessus du gant.
  9. À l'aide de fils, connectez la broche 3V3 de la plume à la broche VIN de l'accéléromètre
  10. À l'aide de fils, connectez la broche GND de la plume à la broche GND de l'accéléromètre.
  11. À l'aide de fils, connectez la broche SCL de la plume à la broche SCL de l'accéléromètre.
  12. À l'aide de fils, connectez la broche SDA de la plume à la broche SDA de l'accéléromètre.
  13. Connectez au moins une batterie de 5 volts via USB à la plume pour fournir de l'énergie.

Étape 3: Aimants

Aimants
Aimants

Étape 1: Placez les deux aimants de force égale l'un en face de l'autre.

Étape 2: mesurez 30 cm d'écart entre les deux aimants

Étape 3: placez le magnétomètre exactement au milieu des deux aimants. Vous devriez recevoir des données autour de 0 alors qu'elles sont au milieu. Si vous recevez une lecture de zéro, passez à l'étape 5.

Étape 4: Si la lecture n'est pas nulle ou proche de zéro, vous devez ajuster la distance des aimants. Si la lecture est négative, déplacez l'aimant gauche d'un cm ou 2 vers la gauche ou jusqu'à ce que la lecture soit zéro. S'il est positif, faites la même chose sauf avec le bon aimant.

Étape 5: Écrivez un code qui accepte les données du magnétomètre et lit si elles sont positives ou négatives. Si positif, le code trace une ligne vers la droite et si négatif, trace une ligne vers la gauche.

Étape 4: Coder

Code
Code

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

Introduction:

Afin de traiter les données de l'accéléromètre, une relation client/serveur doit être établie entre la plume Adafruit et le serveur qui traite les données (fonctionnant sur un ordinateur portable/de bureau). Deux fichiers de code devront être créés: un pour le client (la plume d'Adafruit), et l'autre pour le serveur (dans ce cas, l'ordinateur portable de Jarod). Le client est écrit en C++ et le serveur est écrit en python. Le langage utilisé pour le client est important car Arduino est principalement un langage C++, et il est difficile de le changer pour utiliser un autre langage. Le serveur peut être écrit dans n'importe quelle langue, à condition qu'il dispose de fonctionnalités réseau.

Configuration du client:

Tout d'abord, nous allons configurer le code client. La plupart des codes de connexion WiFi sont facilement disponibles via les bibliothèques Adafruit. Nous commençons par inclure les classes pertinentes.

#include #include #include #include #include

Définissez quelques variables qui seront utilisées tout au long du code.

// Connexion à un réseau const char* ssid = "MMServer"; const char* mot de passe = "MMServer-Password"; // IP et port du serveur qui recevra les données const char* host = "149.160.251.3"; const int port = 12347; bool connecté = faux;

// Initialiser le détecteur de mouvement

Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0(1000);

Client WiFiClient;

Créez une fonction setup() qui sera exécutée dès le démarrage de la plume.

// Configurez la connexion WiFi et connectez-vous au servervoid setup() { Serial.begin(9600); retard (100);

Serial.println();

Serial.println(); Serial.print("Connexion à "); Serial.println(ssid); // Démarrer WiFi WiFi.begin(ssid, mot de passe); // Connexion… while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Connexion réussie au WiFi Serial.println(""); Serial.println("WiFi connecté"); Serial.println("Adresse IP: "); Serial.println(WiFi.localIP());

#ifndef ESP8266

while(!Série); #endif Serial.begin(9600); Serial.println ("Test du capteur");

// Initialiser le capteur

if(!lsm.begin()) { // Il y a eu un problème lors de la détection du LSM9DS0 Serial.print(F("Oups, pas de LSM9DS0 détecté … Vérifiez votre câblage ou I2C ADDR!")); tandis que(1); } Serial.println(F("Trouvé LSM9DS0 9DOF")); // Commencer la connexion au serveur Serial.print("Connexion à "); Serial.println(hôte);

// Vérifier la connexion réussie. En cas d'échec, abandonner

if (!client.connect(hôte, port)) { Serial.println("la connexion a échoué"); connecté = faux; revenir; } else { connecté = vrai; }

//Configurer le gain du capteur et le temps d'intégration

configureSensor(); }

Nous avons alors besoin d'une fonction de boucle qui bouclera à plusieurs reprises. Dans ce cas, il est utilisé pour envoyer à plusieurs reprises les données de l'accéléromètre au serveur sous la forme de « [z_accel]:[y_mag]:[z_mag] ». Le client.print(nombres); fonction est ce qui envoie des données au serveur.

boucle vide () { délai (250); if(connected){ // Ceci enverra les données au serveur sensor_event_t accel, mag, gyro, temp; lsm.getEvent(&accel, &mag, &gyro, &temp); Numéros de chaîne; nombres += accel.acceleration.z; nombres += ":"; nombres += mag.magnetic.y; nombres += ":"; nombres += mag.magnetic.z; Serial.print(chiffres); client.print(nombres); Serial.println(); } else { établirConnexion(); } }

Pour certaines fonctions utilitaires, nous en avons besoin pour établir la connexion entre la plume et le serveur.

voidestablishConnection(){ if (!client.connect(host, port)) { Serial.println("la connexion a échoué"); connecté = faux; revenir; } else { connecté = vrai; } }

Nous devons également configurer le capteur et lui donner la plage de valeurs qu'il lira. Par exemple, l'accélération a 5 options pour la plage: 2g, 4g, 6g, 8g et 16g.

void configureSensor(void){ // Définir la plage de l'accéléromètre //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); // Définir la sensibilité du magnétomètre //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_2GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_4GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_8GAUSS); lsm.setupMag(lsm. LSM9DS0_MAGGAIN_12GAUSS);

// Configuration du gyroscope

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

Configuration du serveur:

Le serveur sera un fichier python qui s'exécutera sur la ligne de commande d'un ordinateur. Pour commencer, importez les classes requises.

import socketimport re import pyautogui

socket est utilisé pour la mise en réseau. re est utilisé pour les regex ou les manipulations de chaînes. pyautogui est une bibliothèque python qui permettra le dessin (discuté plus loin).

Ensuite, nous devons définir quelques variables. Ce seront des variables globales, elles seront donc accessibles dans plusieurs fonctions. Ils seront utilisés plus tard dans le code.

i = 0n = 0 ligne = 1

liste_données =

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 = Faux

first_data = Vrai

Nous avons maintenant besoin d'une fonction pour créer un serveur et l'ouvrir pour les connexions entrantes.

def startServer(): global i global first_data # initialiser le socket du serveur serversocket = socket.socket(socket. AF_INET, socket. SOCK_STREAM) serversocket.setsockopt(socket. SOL_SOCKET, socket. SO_REUSEADDR, 1) # Adresse IP du serveur et hôte du port = " 149.160.251.3" port = 12347 server_address = (hôte, port) # Ouvrir le serveur et écouter les connexions entrantes print ('Démarrage du serveur sur %s port %s' % server_address) serversocket.bind(server_address) serversocket.listen(5) # Attendre les connexions… while True: print ('En attente de connexion…') # Accepter une connexion entrante (clientsocket, adresse) = serversocket.accept() # Essayer d'analyser les données reçues try: print ('Connexion établie à partir de ', adresse) while True: # Recevoir les données et les envoyer pour traitement data = 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 finalement: # Fermez le socket pour éviter les fuites de données inutiles clientsocket.close()

Nous avons maintenant besoin des fonctions qui traiteront toutes les données. La première étape à franchir, et la première fonction appelée, est l'étalonnage du capteur à des fins de calcul.

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)

Ensuite, nous créons un décalage d'accélération mobile. Cela permet au programme de reconnaître quand quelqu'un arrête de bouger son doigt, car toutes les valeurs d'accélération envoyées au serveur doivent être les mêmes à ce moment-là.

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 ou z_diff < -0.2): # mouvement détecté dans les données, redémarrer keep_offset = True n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = pause sinon keep_offset: # stationnaire dans les données, définir un nouveau z_offset z_offset = z_moving_offset print("Nouveau z_offset: ") print(z_offset) n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = keep_offset = Faux keep_offset = Faux

Ensuite, nous faisons le gros du calcul. Cela implique de traduire les données d'accélération en données de position qui nous permettront de dire la direction dans laquelle l'utilisateur déplace son doigt.

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 = list[1] mag_z = list[2] left = False right = False # Ne pas traiter l'accélération avant d'être absolument certain qu'elle s'est accélérée # Empêche le bruit mécanique de contribuer à la position if(z_real -0.20): z_real = 0 #Begin intégrations pour trouver la position 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): mouvement (50, int(z_pos* 1000)) elif(gauche): mouvement(-50, int(z_pos*1000)) z_velo = 0 z_pos = 0

Maintenant, enfin, nous déplaçons le curseur ! Pour ce faire, nous avons ouvert une fenêtre de peinture et l'avons rendue en plein écran. La bibliothèque pyautogui contient une fonction appelée pyautogui.dragRel(x, y); que nous utilisons pour faire glisser le curseur de la souris d'un point à l'autre. Il utilise des données de position relative afin que le mouvement soit relatif à la dernière position du curseur.

def mouvement(x, y): print("déplacement vers", x, -y) pyautogui.dragRel(x, -y)

Enfin, nous devons appeler la fonction principale pour même permettre à tout ce code de s'exécuter.

# Appelle la fonction pour commencer le serverstartServer()