2025 Müəllif: John Day | [email protected]. Son dəyişdirildi: 2025-01-13 06:56
Giriş
Sehrli Əl, əlilliyi olan və motor bacarıqları məhdud olan insanların simulyasiya edilmiş bir mühitdə rəsm və yazı yaradıcılığından zövq almasına imkan verir. Sehrli Əl, şəhadət barmağınızın hərəkətini hiss edən və onu kompüter ekranında xətlərin çəkilməsinə çevirən geyinə bilən bir əlcəkdir.
Lazım olan materiallar
LSM9DOF Breakout Board --- 24.95 dollar ---
Wifi ilə Adafruit Tüyü --- 18.95 dollar ---
Dişi/Dişi Tellər --- 1.95 $ ---
Bant/Velcro zolaqları-3 dollar
Bərabər gücə malik iki maqnit-Qiymətlər dəyişir
Bu necə işləyir
Bir akselerometr istifadə edərək, istifadəçinin barmağının nə vaxt yuxarı və aşağı hərəkət etdiyini təyin etməyə kömək edəcək y oxu üçün sürətləndirmə məlumatlarını toplaya bilərik. Sürətölçənimiz yerin mərkəzinə görə sürətlənməni ölçdüyünə görə x oxunun (sola və ya sağa) sürətlənməsini təyin edə bilmirik. Xoşbəxtlikdən LSM9DOF qırılma lövhəsində maqnit sahələri haqqında məlumat toplamağa imkan verən bir maqnitometr də var. Bir -birindən 30 sm aralıda iki maqnit qoyuruq və əlcək aramızda olur. Maqnit məlumatları müsbət oxunursa, əlcəyin sağa və əksinə hərəkət etdiyini bilirik. Bütün məlumatlar akselerometrdə/maqnitometrdə toplandıqdan sonra, məlumatları tel vasitəsilə wifi kompüterinə qoşulmuş lələkə göndərir və sonra məlumatları kodumuzda istifadə edə biləcəyimiz kompüterə ötürür.
Addım 1: Fiziki Prototip 1
Bu prototip, elektron cihazların üstündən sürüşməsi üçün əlində sərbəst şəkildə tikilmiş əlcəklər üçün nəzərdə tutulmuşdur. Elektron cihaz daha sonra velcro vasitəsi ilə əlindəki əsas əlcəklə birlikdə zirehin alt hissəsinə bağlanacaq. Sonra yaşıl əlcək bazanın və elektron cihazların üzərinə sürüşəcək….
Prototip əlcək hazırlamaq üçün addımlar:
- Əlini izləmək üçün kifayət qədər böyük olan iki parça alın
- Əlinizi hər iki parçanın üzərinə sürün və kəsin
- Mükəmməl hizalanması üçün iki əl kəsikini bir yerə qoyun
- Sonra, tikiş maşını hazırlamaq üçün ipi maşının üzərində göstərilən nöqtələrdən keçirin
- Dikiş maşını qurulduqda, iynəni qaldırın və iki parça parçanı iynənin altına qoyun
- İğnənin kumaşın ən kənarına düzüldüyünə əmin olun, dəzgahı işə salın və parçanın kənarları boyunca tikin, iki parçanı biləkdə tikilməmiş qoyun ki, bir əl daxil olsun.
Addım 2: Fiziki Prototip 2
Son prototipimiz, hər bilək üçün tənzimlənən Velcro kəmərlə birləşdirilmiş adi bir əlcəkdir. Əlcək və kəmər bir -birinə tikilir və elektron cihazlar əlcəyə Velcro vasitəsi ilə bağlanır.
Əlcəyin ikinci prototipini hazırlamaq üçün addımlar:
- Bir əlcək alın, əlcəyin materialının əhəmiyyəti yoxdur.
- Bir cırtdan bilək kəməri alın
- Portativ batareya alın
- Yapışqan Velcro satın alın
- Bir tikiş iynəsi ilə velcro bilək kəmərini əlcəyin altına bağlayın
- Bilək kəməri müxtəlif bilək ölçülərinə uyğunlaşa bilməlidir.
- Yapışqan lenti akselerometrin əsasına yapışdırın və əlcəyin şəhadət barmağına yapışdırın
- Tüyə yapışqan bant bağlayın və əlcəyin üstünə yapışdırın.
- Tellərdən istifadə edərək lələkdəki 3V3 pinini akselerometrdəki VIN pininə bağlayın
- Tellərdən istifadə edərək lələkdəki GND pinini akselerometrə GND pininə bağlayın.
- Tellərdən istifadə edərək lələkdəki SCL pinini akselerometrə SCL pininə bağlayın.
- Tellərdən istifadə edərək, lələkdəki SDA pinini sürətləndiriciyə SDA pininə bağlayın.
- Güc təmin etmək üçün ən az 5 voltluq bir batareyanı USB vasitəsilə tükə bağlayın.
Addım 3: Mıknatıslar
Addım 1: İki bərabər maqnitləri bir -birinə qarşı qoyun.
Addım 2: İki maqnit arasındakı 30 sm boşluğu ölçün
Addım 3: Maqnitometrini iki maqnitin tam ortasına qoyun. Ortada olarkən 0 ətrafında məlumat almalısınız. Sıfır oxuyursunuzsa, 5 -ci addıma keçin.
Addım 4: Oxumaq sıfır deyilsə və ya sıfıra yaxındırsa, maqnitlərin məsafəsini tənzimləməlisiniz. Oxumaq mənfi olarsa, sol mıknatısı bir sm və ya 2 sola və ya sıfıra qədər hərəkət etdirin. Müsbət olarsa, doğru mıknatısdan başqa eyni şeyi edin.
Addım 5: Maqnitometrdən məlumatları qəbul edən və müsbət və ya mənfi olduğu halda oxuyan kod yazın. Əgər kod müsbətdirsə, sağa, mənfi isə sola bir xətt çəkin.
Addım 4: Kod
github.iu.edu/ise-e101-F17/MuscleMemory-Sw…
Giriş:
Sürətölçəndən məlumatları emal etmək üçün, Adafruit lələyi ilə məlumatları işləyən server arasında (noutbukda/masaüstündə işləyən) müştəri/server əlaqəsi qurulmalıdır. İki kod faylı yaradılmalıdır: biri müştəri üçün (Adafruit lələyi), digəri isə server üçün (bu halda Jarodun noutbuku). Müştəri C ++, server isə python ilə yazılmışdır. Müştəri üçün istifadə olunan dil vacibdir, çünki Arduino əsasən C ++ dilidir və onu başqa bir dildə istifadə etmək üçün dəyişdirmək çətindir. Server şəbəkə xüsusiyyətlərinə malik olduğu müddətdə istənilən dildə yazıla bilər.
Müştərinin qurulması:
Əvvəlcə müştəri kodunu quracağıq. WiFi bağlantısı kodunun çoxu Adafruit kitabxanaları vasitəsilə əldə edilə bilər. Müvafiq sinifləri daxil etməklə başlayırıq.
#daxil edin #daxil edin #daxil edin #daxil edin
Kod boyunca istifadə ediləcək bəzi dəyişənləri təyin edin.
// Şəbəkəyə qoşul char* ssid = "MMServer"; const char* parol = "MMServer-Şifrə"; // məlumatları alacaq serverin IP və portu char* host = "149.160.251.3"; const int port = 12347; bool bağlı = yanlış;
// Hərəkət detektorunu işə salın
Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0 (1000);
WiFi müştəri;
Lələk başlayan kimi işləyəcək bir setup () funksiyası yaradın.
// WiFi bağlantısı qurun və servervoid qurulmasına qoşulun () {Serial.begin (9600); gecikmə (100);
Serial.println ();
Serial.println (); Serial.print ("Bağlanır"); Serial.println (ssid); // WiFi WiFi -ə başlayın. Başlayın (ssid, parol); // Bağlanır… while (WiFi.status ()! = WL_CONNECTED) {gecikmə (500); Serial.print ("."); } // WiFi Serial.println ("") ilə uğurla bağlandı; Serial.println ("WiFi bağlıdır"); Serial.println ("IP ünvanı:"); Serial.println (WiFi.localIP ());
#ifndef ESP8266
while (! Serial); #endif Serial.begin (9600); Serial.println ("Sensor Testi");
// Sensoru işə salın
if (! lsm.begin ()) {// LSM9DS0 Serial.print (F ("Ooops, LSM9DS0 aşkarlanmadı… Kablolarınızı yoxlayın və ya I2C ADDR!") aşkarlanarkən problem yarandı); isə (1); } Serial.println (F ("LSM9DS0 9DOF tapıldı")); // Serial.print serverinə qoşulmağa başlayın ("Bağlanır"); Serial.println (ev sahibi);
// Uğurlu əlaqəni yoxlayın. Əgər uğursuz olarsa, abort edin
if (! client.connect (host, port)) {Serial.println ("bağlantı uğursuz oldu"); bağlı = yalan; qayıtmaq; } başqa {bağlı = doğru; }
// Sensor qazancını və inteqrasiya müddətini təyin edin
configureSensor (); }
Daha sonra təkrarlanan bir döngə funksiyasına ehtiyacımız var. Bu vəziyyətdə, akselerometrdən "[z_accel]: [y_mag]: [z_mag]" şəklində serverə məlumatları dəfələrlə göndərmək üçün istifadə olunur. Müştəri. Çap (nömrələr); serverə məlumat göndərən funksiyadır.
void loop () {gecikmə (250); if (bağlı) {// Bu məlumatları sensors_event_t accel, mag, gyro, temp serverinə göndərəcək; lsm.getEvent (& accel, & mag, & gyro, & temp); String nömrələri; ədədlər += accel.acceleration.z; ədədlər = = ":"; ədədlər += mag.magnetic.y; ədədlər = = ":"; ədədlər += mag.magnetic.z; Serial. çap (nömrələr); müştəri çapı (nömrələr); Serial.println (); } başqa {installConnection (); }}
Bəzi yardımçı funksiyalar üçün lələklə server arasında əlaqə qurmaq lazımdır.
void installConnection () {if (! client.connect (host, port)) {Serial.println ("bağlantı uğursuz oldu"); bağlı = yalan; qayıtmaq; } başqa {bağlı = doğru; }}
Sensoru konfiqurasiya etməli və oxuyacağı dəyərlər aralığını verməliyik. Məsələn, sürətləndirmə aralığında 5 seçim var: 2g, 4g, 6g, 8g və 16g.
void configureSensor (void) {// Akselerometr aralığını təyin edin //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); // Maqnitometr həssaslığını təyin edin //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_2GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_4GAUSS); //lsm.setupMag(lsm. LSM9DS0_MAGGAIN_8GAUSS); lsm.setupMag (lsm. LSM9DS0_MAGGAIN_12GAUSS);
// Giroskopu qurun
lsm.setupGyro (lsm. LSM9DS0_GYROSCALE_245DPS); //lsm.setupGyro(lsm. LSM9DS0_GYROSCALE_500DPS); //lsm.setupGyro(lsm. LSM9DS0_GYROSCALE_2000DPS); }
Serverin qurulması:
Server, bir kompüterin əmr satırında işləyəcək bir python faylı olacaq. Başlamaq üçün lazım olan sinifləri idxal edin.
idxalı yenidən idxal edin
socket şəbəkə qurmaq üçün istifadə olunur. re, regex və ya simli manipulyasiyalar üçün istifadə olunur. pyautogui, rəsmin baş verməsinə imkan verən bir python kitabxanasıdır (daha sonra müzakirə ediləcək).
Sonra, bəzi dəyişənləri təyin etməliyik. Bunlar qlobal dəyişənlər olacaq, buna görə birdən çox funksiyada əldə ediləcəklər. Daha sonra kodda istifadə ediləcəklər.
i = 0n = 0 xətt = 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 = Yanlış
first_data = Doğrudur
İndi server yaratmaq və daxil olan əlaqələr üçün açmaq üçün bir funksiyaya ehtiyacımız var.
def startServer (): global i global first_data # server socket serversocket = socket.socket (socket. AF_INET, socket. SOCK_STREAM) serversocket.setsockopt (socket. SOL_SOCKET, socket. SO_REUSEADDR, 1) # Server IP ünvanı və port host = " 149.160.251.3 "port = 12347 server_address = (host, port) # Serveri açın və daxil olan əlaqələri dinləyin (' %s portda %s serverdə %server_addressə başlayın) serversocket.bind (server_address) serversocket.listen (5) # Bağlantıları gözləyin… Doğru olarkən: çap edin ('Bağlantı gözləyir…') # Gələn bir əlaqəni qəbul edin (clientocket, address) = serversocket.accept () # Alınan məlumatları təhlil etməyə çalışın: print ('Bağlantı quruldu', ünvan)) True isə: # Veriləri alın və məlumatların işlənməsi üçün göndərin = 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) başqa: moveAcce l (accel_data [0]) processData (accel_data) first_data = Nəhayət yalan: # Lazımsız məlumat sızıntısının qarşısını almaq üçün yuvanı bağlayın clientsocket.close ()
İndi bütün məlumatları emal edəcək funksiyalara ehtiyacımız var. Atılacaq ilk addım və çağırılan ilk funksiya hesablama məqsədləri üçün sensorun kalibridir.
def calibData (siyahı): qlobal z_calib qlobal z_offset qlobal mag_data qlobal mag_calib_y qlobal mag_offset_y z_calib += float (siyahı [0]) mag_calib_y += float (siyahı [1]) əgər (i == 50): z_offset = z_calib / 50 mag_offset = mag_calib_y / 50 z_calib = 0 mag_calib_y = 0 mag_data.append (mag_offset_y)
Sonra, hərəkət edən bir sürətlənmə ofsetini yaradırıq. Bu, proqramın kimsə barmağını hərəkət etməyi dayandırdığını tanıyacağını təmin edir, çünki serverə göndərilən sürətləndirmə dəyərlərinin hamısı eyni vaxtda olmalıdır.
def moveAccel (sayı): qlobal z_calib qlobal z_diff qlobal z_moving_offset qlobal z_offset qlobal data_list qlobal n qlobal keep_offset əgər (n 0.2 və ya z_diff <-0.2): # hərəkət data daxilində aşkar edilərsə, keep_offset = True n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = break_offset olmadıqda fasilə: məlumatda # stasionar, yeni z_offset z_offset = z_moving_offset çapını təyin edin ("Yeni z_offset:") çap (z_offset) n = 0 z_calib = 0 z_moving_offset = 0 z_diff = 0 data_list = keep_offset = Yanlış keep_offset = Yanlış
Sonra, riyaziyyatın ən böyük zərbəsini edirik. Bu, sürətləndirmə məlumatlarının istifadəçinin barmağının hərəkət istiqamətini söyləməyimizə imkan verən bir mövqe məlumatına çevrilməsini əhatə edir.
def processData (siyahı): #[accel.z, mag.y] qlobal z_offset qlobal z_real qlobal z_velo qlobal z_pos qlobal birinci_data qlobal mag_data
z_real = float (siyahı [0]) - z_offset
mag_y = siyahı [1] mag_z = siyahı [2] sol = Yanlış sağ = Yanlış # Sürətləndiyinə tam əmin olana qədər sürətləndirməni işlətməyin # (z_real -0.20) olduqda mexaniki səs -küyün mövqeyə töhfə verməsinin qarşısını alır: z_real = 0 #Begin mövqe tapmaq üçün inteqrasiyalar (ilk_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) başqa: 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): sağ = Əsl elif (float (mag_data [1]) - float (mag_data [0]) <-0.03): left = Doğru olarsa (sağda): hərəkət (50, int (z_pos*) 1000)) elif (solda): hərəkət (-50, int (z_pos*1000)) z_velo = 0 z_pos = 0
İndi, nəhayət, kursoru hərəkət etdiririk! Bunu etmək üçün bir boya pəncərəsi açdıq və onu tam ekrana çevirdik. Pyautogui kitabxanasında pyautogui.dragRel (x, y) adlı funksiya var; siçan kursorunu bir nöqtədən digərinə sürükləmək üçün istifadə edirik. Nisbi mövqe məlumatlarını istifadə edir, buna görə hərəkət kursorun son mövqeyinə nisbətlidir.
def hərəkəti (x, y): çap ("hərəkət etmək", x, -y) pyautogui.dragRel (x, -y)
Nəhayət, bütün bu kodların işləməsinə icazə vermək üçün əsas funksiyaya zəng etməliyik.
# ServerstartServer () funksiyasına başlamaq üçün funksiyanı çağırır