Accel Writing (Կախարդական ձեռք). 4 քայլ (նկարներով)
Accel Writing (Կախարդական ձեռք). 4 քայլ (նկարներով)
Accel Writing (Կախարդական ձեռք)
Accel Writing (Կախարդական ձեռք)
Accel Writing (Կախարդական ձեռք)
Accel Writing (Կախարդական ձեռք)
Accel Writing (Կախարդական ձեռք)
Accel Writing (Կախարդական ձեռք)

Ներածություն

Կախարդական ձեռքը թույլ է տալիս հաշմանդամություն ունեցող և շարժիչ հմտություններ ունեցող մարդկանց վայելել նկարչության և գրելու ստեղծագործականությունը մոդելավորված միջավայրում: Կախարդական ձեռքը կրելի ձեռնոց է, որը զգում է ձեր ցուցամատի շարժումը և այն թարգմանում է համակարգչի էկրանին գծերի գծագրման:

Անհրաժեշտ նյութեր

LSM9DOF Breakout Board --- 24,95 դոլար ---

Adafruit փետուրը WiFi- ով --- 18,95 դոլար ---

Իգական/իգական լարեր --- 1,95 դոլար ---

Կասետային/Velcro շերտեր --- $ 3

Երկու հավասար ուժ ունեցող մագնիսներ --- Գները տարբեր են

Ինչպես է դա աշխատում

Արագացուցիչի միջոցով մենք կարող ենք y- առանցքի արագացման տվյալներ հավաքել, որոնք կօգնեն մեզ որոշել, թե երբ է օգտագործողի մատը շարժվում վեր ու վար: Քանի որ մեր արագացուցիչը չափում է արագացումը երկրի կենտրոնի նկատմամբ, մենք չենք կարող որոշել x առանցքի արագացումը (ձախ կամ աջ): Բարեբախտաբար, LSM9DOF ճեղքման տախտակը պարունակում է նաև մագնիսաչափ, որը թույլ է տալիս մեզ հավաքել տվյալներ մագնիսական դաշտերի վերաբերյալ: Մենք երկու մագնիս ենք տեղադրում 30 սմ հեռավորության վրա, իսկ ձեռնոցը ՝ մեջտեղում: Եթե մագնիսական տվյալները դրական են ընթերցվում, ապա մենք գիտենք, որ ձեռնոցը շարժվում է աջ և հակառակը: Արագացուցիչի/մագնիսաչափի մեջ բոլոր տվյալները հավաքելուց հետո այն տվյալները մետաղալարով ուղարկում է wifi համակարգչին միացված փետուրին, այնուհետև տվյալները փոխանցում համակարգչին, որը մենք կարող ենք օգտագործել մեր ծածկագրում:

Քայլ 1: Ֆիզիկական նախատիպ 1

Ֆիզիկական նախատիպ 1
Ֆիզիկական նախատիպ 1
Ֆիզիկական նախատիպ 1
Ֆիզիկական նախատիպ 1

Այս նախատիպը նախատեսված է ձեռքի վրա կարված ձեռնոցով, որպեսզի այն սայթաքի էլեկտրոնային սարքերի վրայով: Էլեկտրոնային սարքն այնուհետև velcro- ով կցվելու է զրահապատ թևի հիմքին ՝ ձեռքի հիմնական ձեռնոցի հետ համատեղ: Հետո կանաչ ձեռնոցը կսահի բազայի և էլեկտրոնային սարքերի վրա…

Ձեռնոցի նախատիպը պատրաստելու քայլերը

  • Ձեռքի հետք վերցնելու համար բավական մեծ երկու կտոր կտոր վերցրեք
  • Ձեռքով հետք տվեք գործվածքների երկու կտորներին և կտրեք դրանք
  • Երկու ձեռքով կտրված հատվածները միացրեք այնպես, որ դրանք կատարյալ հարթեցված լինեն
  • Հաջորդը, կարի մեքենան պատրաստելու համար, շարանը անցեք մեքենայի վրա նշված կետերի միջով
  • Երբ կարի մեքենան տեղադրվի, բարձրացրեք ասեղը և ասեղի տակ դրեք գործվածքների երկու կտորները
  • Համոզվեք, որ ասեղը շարված է գործվածքների հենց ծայրին, գործարկեք մեքենան և կարեք գործվածքների եզրերի երկայնքով, մինչդեռ երկու կտորները դաստակի մոտ չկտրված թողեք, որպեսզի ձեռքը տեղավորվի:

Քայլ 2: Ֆիզիկական նախատիպ 2

Ֆիզիկական նախատիպ 2
Ֆիզիկական նախատիպ 2
Ֆիզիկական նախատիպ 2
Ֆիզիկական նախատիպ 2

Մեր վերջնական նախատիպը սովորական ձեռնոց է ՝ զուգորդված Velcro ժապավենով, որը կարգավորելի է ցանկացած դաստակի համար: Ձեռնոցն ու ժապավենը կարված են միասին, իսկ էլեկտրոնային սարքերը Velcro- ի միջոցով ամրացվում են ձեռնոցին:

Ձեռնոցի երկրորդ նախատիպի պատրաստման քայլերը.

  1. Ձեռք ձեռք բերեք, ձեռնոցի նյութը նշանակություն չունի:
  2. Գնեք Velcro դաստակի ժապավեն
  3. Գնեք շարժական մարտկոց
  4. Գնեք Կպչուն Velcro
  5. Կարի ասեղով ամրացրեք թավշյա դաստակի ժապավենը ձեռնոցի հիմքին
  6. Դաստակի ժապավենը պետք է կարողանա հարմարվել դաստակի տարբեր չափերին:
  7. Կպչուն ժապավենը ամրացրեք արագացուցիչի հիմքին և ամրացրեք ձեռնոցի ցուցամատին
  8. Կպչուն ժապավենը ամրացրեք փետուրին և ամրացրեք այն ձեռնոցի վերևում:
  9. Լարերի միջոցով միացրեք փետուրի մեջ 3V3 կապը արագացուցիչի VIN կապին
  10. Լարերի օգնությամբ միացրեք փետուրի մեջ տեղադրված GND կապը արագացուցիչի GND կապին:
  11. Հաղորդալարերի միջոցով SCL- ի փետուրը միացրեք փետուրի SCL- ի արագացուցիչին:
  12. Լարերի միջոցով միացրեք SDA- ի փետուրը փետուրի SDA արագիչաչափին:
  13. Էլեկտրաէներգիա ապահովելու համար USB- ի միջոցով միացրեք առնվազն 5 վոլտ մարտկոց USB- ի միջոցով:

Քայլ 3: Մագնիսներ

Մագնիսներ
Մագնիսներ

Քայլ 1: Հավասար ուժի երկու մագնիսները տեղադրեք միմյանց դիմաց:

Քայլ 2. Չափեք երկու մագնիսների միջև 30 սմ հեռավորությունը

Քայլ 3. Մագնիսաչափը տեղադրեք երկու մագնիսների ճիշտ մեջտեղում: Դուք պետք է ստանաք տվյալներ 0 -ի սահմաններում, մինչ դրանք մեջտեղում են: Եթե զրոյական ցուցանիշ եք ստանում, անցեք 5 -րդ քայլին:

Քայլ 4: Եթե ընթերցումը զրոյական չէ կամ զրոյին մոտ, ապա դուք պետք է կարգավորեք մագնիսների հեռավորությունը: Եթե ցուցանիշը բացասական է, ձախ մագնիսը տեղափոխեք սմ կամ 2 սմ դեպի ձախ կամ մինչև ընթերցումը զրո լինի: Եթե դա դրական է, նույնը կատարեք, բացառությամբ ճիշտ մագնիսի:

Քայլ 5: Գրեք ծածկագիր, որը ընդունում է տվյալները մագնիսաչափից և կարդում է այն դրական կամ բացասական: Եթե դրական է, կոդը գծի՛ր աջ, իսկ եթե բացասական ՝ գծի՛ր ձախ:

Քայլ 4: Կոդ

Կոդ
Կոդ

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

Ներածություն:

Արագացուցիչից տվյալների մշակման համար պետք է հաճախորդ/սերվեր հարաբերություններ հաստատել Adafruit փետուրի և տվյալները մշակող սերվերի միջև (աշխատում է նոութբուքի/աշխատասեղանի վրա): Պետք է ստեղծվի երկու ծածկագրային ֆայլ ՝ մեկը հաճախորդի համար (Adafruit փետուրը), իսկ մյուսը սերվերի համար (այս դեպքում ՝ Յարոդի նոութբուքը): Հաճախորդը գրված է C ++ - ով, իսկ սերվերը `Python- ով: Հաճախորդի համար օգտագործվող լեզուն կարևոր է, քանի որ Arduino- ն հիմնականում C ++ լեզու է, և դժվար է այն փոխել այլ լեզվով: Սերվերը կարող է գրվել ցանկացած լեզվով, քանի դեռ այն ունի ցանցային հնարավորություններ:

Հաճախորդի կարգավորում

Նախ, մենք կկարգավորենք հաճախորդի կոդը: WiFi կապի կոդի մեծ մասը հեշտությամբ հասանելի է Adafruit գրադարանների միջոցով: Մենք սկսում ենք ներառելով համապատասխան դասարաններ:

#ներառել #ներառել #ներառել #ներառել #ներառել

Որոշ փոփոխականներ սահմանեք, թե ինչ է օգտագործվելու ծածկագրում:

// Միացեք ցանցին char char* ssid = "MMS սերվեր"; const char* գաղտնաբառ = "MMS սերվեր-գաղտնաբառ"; // սերվերի IP և պորտ, որը կստանա տվյալներ const char* host = "149.160.251.3"; const int նավահանգիստ = 12347; bool կապված = կեղծ;

// Շարժման դետեկտորի սկզբնականացում

Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0 (1000);

WiFiClient հաճախորդ;

Ստեղծեք setup () գործառույթ, որը կգործարկվի փետուրը սկսելուն պես:

// Կարգավորեք WiFi կապը և միացեք servervoid կարգավորմանը () {Serial.begin (9600); ուշացում (100);

Serial.println ();

Serial.println (); Serial.print («Միացում»); Serial.println (ssid); // Գործարկել WiFi WiFi.begin (ssid, գաղտնաբառ); // Միացում… while (WiFi.status ()! = WL_CONNECTED) {հետաձգում (500); Serial.print ("."); } // Հաջողությամբ միացված է WiFi Serial.println (""); Serial.println («WiFi միացված է»); Serial.println ("IP հասցե` "); Serial.println (WiFi.localIP ());

#ifndef ESP8266

իսկ (! Սերիա); #endif Serial.begin (9600); Serial.println («Սենսորային թեստ»);

// Սկսեք սենսորը

if (! lsm.begin ()) {// Խնդիր առաջացավ LSM9DS0 Serial.print- ի հայտնաբերման ժամանակ (F («Օհ, LSM9DS0 չի հայտնաբերվել … Ստուգեք ձեր էլեկտրագծերը կամ I2C ADDR!»)); մինչդեռ (1); } Serial.println (F («Գտնվել է LSM9DS0 9DOF»)); // Սկսեք միանալ սերվերին Serial.print («Միացում»); Serial.println (հաղորդավար);

// Ստուգեք հաջող կապի համար: Եթե ձախողվեց, ապա ընդհատեք

if (! client.connect (հյուրընկալող, նավահանգիստ)) {Serial.println («կապը ձախողվեց»); կապված = կեղծ; վերադարձ; } else {կապված = ճշմարիտ; }

// Կարգավորեք սենսորի շահույթի և ինտեգրման ժամանակը

configureSensor (); }

Այնուհետև մեզ անհրաժեշտ է օղակի գործառույթ, որը բազմիցս կշրջվի: Այս դեպքում այն օգտագործվում է արագացուցիչից տվյալները սերվերին բազմիցս ուղարկելու համար «[z_accel]: [y_mag]: [z_mag]» տեսքով: Հաճախորդը: տպել (թվեր); գործառույթը այն է, ինչ տվյալներ է ուղարկում սերվեր:

void loop () {հետաձգում (250); եթե (կապված է) {// Սա տվյալներ կուղարկի սերվերին sensors_event_t accel, mag, gyro, temp; lsm.getEvent (& accel, & mag, & gyro, & temp); Լարային համարներ; թվեր += accel.acceleration.z; թվեր += ":"; թվեր += mag.magnetic.y; թվեր += ":"; թվեր += mag.magnetic.z; Serial.print (թվեր); client.print (թվեր); Serial.println (); } else {installConnection (); }}

Որոշ օգտակար գործառույթների համար մեզ անհրաժեշտ է մեկը `փետուրի և սերվերի միջև կապ հաստատելու համար:

void installConnection () {if (! client.connect (հյուրընկալող, նավահանգիստ)) {Serial.println («կապը ձախողվեց»); կապված = կեղծ; վերադարձ; } else {կապված = ճշմարիտ; }}

Մենք նաև պետք է կազմաձևենք սենսորը և տանք այն ընթերցված արժեքների շրջանակ: Օրինակ ՝ արագացումը 5 տարբերակ ունի միջակայքի համար ՝ 2 գ, 4 գ, 6 գ, 8 գ և 16 գ:

void configureSensor (void) {// Սահմանել արագացուցիչի տիրույթը //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); // Սահմանել մագնիսաչափի զգայունությունը //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_2GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_4GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_8GAUSS); lsm.setupMag (lsm. LSM9DS0_MAGGAIN_12GAUSS);

// Կարգավորեք գիրոսկոպը

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

Սերվերի կարգավորում

Սերվերը կլինի պիթոնի ֆայլ, որը կաշխատի համակարգչի հրամանի տողում: Սկսելու համար ներմուծեք անհրաժեշտ դասերը:

ներմուծել socketimport կրկին ներմուծել pyautogui

վարդակից օգտագործվում է ցանցի համար: re- ն օգտագործվում է regex կամ լարային մանիպուլյացիաների համար: pyautogui- ը պիթոնի գրադարան է, որը թույլ կտա նկարը կատարել (քննարկվի ավելի ուշ):

Հաջորդը, մենք պետք է որոշենք փոփոխականներ: Սրանք գլոբալ փոփոխականներ են, ուստի դրանք հասանելի կլինեն բազմաթիվ գործառույթներով: Դրանք ավելի ուշ կօգտագործվեն ծածկագրում:

i = 0n = 0 տող = 1

տվյալների_ցանկ =

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 = Կեղծ

first_data = Trueշմարիտ

Այժմ մեզ անհրաժեշտ է սերվեր ստեղծելու և մուտքային միացումների համար բացելու գործառույթ:

def startServer (): գլոբալ i գլոբալ առաջին_տվյալներ # սկզբնականացնել սերվերի վարդակից serversocket = socket.socket (socket. AF_INET, socket. SOCK_STREAM) serversocket.setsockopt (socket. SOL_SOCKET, socket. SO_REUSEADDR, 1) # սերվերի IP հասցե և նավահանգստի հյուրընկալող = " 149.160.251.3 "port = 12347 server_address = (հյուրընկալող, նավահանգիստ) # Բացեք սերվերը և լսեք մուտքային միացումների համար տպեք ('սերվերի մեկնարկը %s նավահանգստում %s' %server_address) serversocket.bind (server_address) serversocket.listen (5) # Սպասեք միացումներին… իսկ ճշմարիտ ՝ տպել («Սպասում է կապին …») # Ընդունել մուտքային միացում (հաճախորդների տուփ, հասցե) = serversocket.accept () # Փորձեք վերլուծել ստացված տվյալները try: print («Կապը հաստատված է», հասցե) while True: # Ստացեք տվյալները և ուղարկեք դրանք տվյալների մշակման համար = 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] տպել (accel_data) i+= 1 եթե (i <51): calibData (accel_data) else: moveAcce l (accel_data [0]) processData (accel_data) first_data = Վերջապես կեղծ. # Փակեք վարդակը ՝ տվյալների անհարկի արտահոսքը կանխելու համար clientocket.close ()

Այժմ մենք պահանջում ենք գործառույթներ, որոնք մշակելու են բոլոր տվյալները: Առաջին քայլը, և առաջին գործառույթը, որը կոչվում է, դա սենսորի ճշգրտումն է հաշվարկման նպատակով:

def calib Տվյալներ (ցանկ). = mag_calib_y / 50 z_calib = 0 mag_calib_y = 0 mag_data.append (mag_offset_y)

Հաջորդը, մենք ստեղծում ենք շարժվող արագացման օֆսեթ: Սա ստիպում է, որ ծրագիրը ճանաչի, երբ ինչ -որ մեկը դադարում է շարժել մատը, քանի որ սերվերին ուղարկվող արագացման բոլոր արժեքները պետք է նույնը լինեն այդ ժամանակ:

def moveAccel (num). գլոբալ z_calib գլոբալ z_diff գլոբալ z_moving_offset գլոբալ z_offset գլոբալ տվյալների_համակարգ գլոբալ n գլոբալ keep_offset եթե (n 0.2 կամ z_diff <-0.2): # տվյալների միջակայքում հայտնաբերված # շարժում, վերագործարկում keep_offset = True n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = ընդմիջում, եթե ոչ keep_offset: # անշարժ տվյալների մեջ, նոր z_offset z_offset = z_moving_offset print ("New z_offset:") print (z_offset) n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = keep_offset = Կեղծ keep_offset = Կեղծ

Հաջորդը, մենք կատարում ենք մաթեմատիկայի ծանրաբեռնվածությունը: Սա ենթադրում է արագացման տվյալների փոխակերպում դիրքի տվյալների, ինչը թույլ կտա մեզ ասել օգտվողի մատը շարժելու ուղղությունը:

def process Տվյալներ (ցուցակ).

z_real = float (ցուցակ [0]) - z_offset

mag_y = ցուցակ [1] mag_z = ցուցակ [2] ձախ = Կեղծ աջ = Սխալ # Մի մշակեք արագացումը մինչև բացարձակապես համոզված չլինի, որ այն արագացրել է # Կանխում է մեխանիկական աղմուկը նպաստել դիրքին, եթե (z_real -0.20): z_real = 0 # Սկիզբ ինտեգրումներ ՝ դիրքը գտնելու համար, եթե (առաջին_տվյալ). 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) այլ կերպ ՝ 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): շարժում (50, int (z_pos* 1000)) elif (ձախ). Շարժում (-50, int (z_pos*1000)) z_velo = 0 z_pos = 0

Հիմա, վերջապես, մենք կուրսորը տեղափոխում ենք: Դա անելու համար մենք բացեցինք ներկի պատուհան և այն դարձրինք ամբողջ էկրան: Pyautogui գրադարանը պարունակում է գործառույթ, որը կոչվում է pyautogui.dragRel (x, y); որը մենք օգտագործում ենք մկնիկի կուրսորը մի կետից մյուսը քաշելու համար: Այն օգտագործում է հարաբերական դիրքի տվյալները, այնպես որ շարժումը հարաբերական է կուրսորի վերջին դիրքի հետ:

def շարժում (x, y). տպել («տեղափոխվել դեպի», x, -y) pyautogui.dragRel (x, -y)

Ի վերջո, մենք պետք է կանչենք հիմնական գործառույթը `նույնիսկ թույլ տալու, որ այս ամբողջ կոդը գործարկվի:

# Callանգահարում է serverstartServer- ը սկսելու գործառույթին ()

Խորհուրդ ենք տալիս: