- Devre şeması
- Servo Motor Kontrolü için GPIO pininde PWM sinyalleri oluşturma
- Robotik Kol için PIC16F8771A Programlama
- PIC Robotik Kol Kodunun Simülasyonu
- EasyEDA kullanarak PCB Tasarımı
- Çevrimiçi Numune Hesaplama ve Sipariş Etme
- PIC Robotik Kolun Çalışması
Otomobil üretim endüstrilerinin montaj hattından uzaydaki telesurji robotlarına kadar her yerde Robotik Kollar bulunur. Bu robotların mekanizmaları, benzer işlevler ve artırılmış yetenekler için programlanabilen bir insana benzer. İnsanlardan daha hızlı ve doğru tekrarlanan eylemleri gerçekleştirmek için kullanılabilirler veya zorlu ortamlarda insan hayatını riske atmadan kullanılabilirler. Arduino'yu kullanarak, belirli bir görevi yapmak için eğitilebilecek ve sonsuza kadar tekrar etmesi için eğitilebilecek bir Kayıt ve Oynatma Robot Kolu oluşturduk.
Bu eğitimde , potansiyometrelerle aynı robotik kolu kontrol etmek için endüstri standardı PIC16F877A 8-bit Mikroişlemciyi kullanacağız. Bu projedeki zorluk, PIC16F877A'nın yalnızca iki PWN özellikli pime sahip olmasıdır, ancak robotumuz için 5 ayrı PWM pini gerektiren yaklaşık 5 servo motoru kontrol etmemiz gerekiyor. Bu nedenle, GPIO pinlerini kullanmalı ve zamanlayıcı kesintilerini kullanarak PIC GPIO pinlerinde PWM sinyalleri oluşturmalıyız. Şimdi, tabii ki daha iyi bir mikro denetleyiciye yükseltebilir veya burada işleri çok daha kolay hale getirmek için bir çoğullayıcı IC kullanabiliriz. Ama yine de, bu projeyi öğrenme deneyimi için denemeye değer.
Bu projede kullandığım robotik kolun mekanik yapısı bir önceki projem için tamamen 3 boyutlu çıktı; tüm tasarım dosyalarını ve montaj prosedürünü burada bulabilirsiniz. Alternatif olarak, bir 3D yazıcınız yoksa, bağlantıda gösterildiği gibi kartonları kullanarak basit bir Robotik Kol da oluşturabilirsiniz. Robot Kolunuzu bir şekilde ele geçirdiğinizi varsayarsak, projeye geçelim.
Devre şeması
Bu PIC Mikroişlemci tabanlı Robotik Kol için Tam devre şeması aşağıda gösterilmiştir. Şematikler EasyEDA kullanılarak çizildi.
Devre şeması oldukça basittir; projenin tamamı 12V adaptör tarafından desteklenmektedir. Bu 12V daha sonra iki adet 7805 Voltaj regülatörü kullanılarak + 5V'ye dönüştürülür. Biri + 5V, diğeri + 5V (2) olarak etiketlenmiştir. İki regülatöre sahip olmanın nedeni, servo döndüğünde, voltaj düşüşü yaratan çok fazla akımı çekmesidir. Bu voltaj düşüşü, PIC'yi kendini yeniden başlatmaya zorlar, bu nedenle hem PIC hem de servo motorları aynı + 5V ray üzerinde çalıştıramayız. Bu nedenle + 5V etiketli olanı PIC Mikroişlemciye, LCD'ye ve Potansiyometrelere güç sağlamak için kullanılır ve + 5V (2) olarak etiketlenmiş ayrı bir regülatör çıkışı servo motorlara güç sağlamak için kullanılır.
Potansiyometrelerin 0V ila 5V arasında değişken bir voltaj sağlayan beş çıkış pini, PIC'in An0 ila AN4 analog pinlerine bağlanır. PWM üretmek için zamanlayıcılar kullanmayı planladığımız için, servo motorlar herhangi bir GPIO pinine bağlanabilir. Servo motorlar için RD2'den RD6'ya kadar pinler seçtim, ancak seçtiğiniz herhangi bir GPIO olabilir.
Program çok fazla hata ayıklama içerdiğinden, 16x2 LCD ekran da PIC'nin B portuna arayüzlenir. Bu, kontrol edilen servo motorların görev döngüsünü gösterecektir. Bunun dışında, gelecekte herhangi bir sensörün arayüzlenmesi gerekmesi ihtimaline karşı, tüm GPIO ve analog pinler için de bağlantıları genişlettim. Son olarak, ICSP programlama seçeneğini kullanarak PIC'yi pickit3 ile doğrudan programlamak için programlayıcı pini H1'i de bağladım.
Servo Motor Kontrolü için GPIO pininde PWM sinyalleri oluşturma
Devre hazır olduğunda, servo motoru kontrol etmek için PIC'in GPIO pininde PWN sinyallerini nasıl üreteceğimizi bulmalıyız. Zamanlayıcı kesme yöntemini kullanarak benzer bir şeyi zaten yorduk ve başarılı olduk. Burada sadece bunun üzerine inşa edeceğiz, bu yüzden burada yeniyseniz, devam etmeden önce bu önceki öğreticiyi okumanızı şiddetle tavsiye ederim.
Tüm hobi servo motorlar 50Hz frekansla çalışır. Bir servo motor için tam bir darbe döngüsü, 20ms olan 1/50 (F = 1 / T) olacaktır. Bu 20 ms'nin tamamında, sinyalin geri kalanı her zaman kapalıyken, kontrol sinyali yalnızca 0 ila 2 ms arasındadır. Aşağıdaki şekil, motoru toplam 20 ms'lik sürenin 0 derecesinden 180 derecesine döndürmek için AÇIK süresinin nasıl sadece 0 ila 2 ms arasında değiştiğini göstermektedir.
Bunu aklımızda tutarak programı, PIC potansiyometreden 0 ila 1204'ü okuyacak ve servo motorun görev döngüsü olacak olan 0 ila 100'e eşleştirecek şekilde yazmalıyız. Bu görev döngüsünü kullanarak servo motorun AÇIK süresini hesaplayabiliriz. Ardından zamanlayıcı kesintisini, Arduino'daki millis () işlevine benzer şekilde davranacak şekilde düzenli bir aralıkta taşacak şekilde başlatabiliriz. Bununla birlikte, GPIO pinini istenen süre için yüksek olacak şekilde değiştirebilir ve 20ms (bir tam döngü) sonra kapatabilir ve ardından aynı işlemi tekrarlayabiliriz. Şimdi, mantığı anladığımıza göre programa girelim.
Robotik Kol için PIC16F8771A Programlama
Her zaman olduğu gibi , bir Video içeren eksiksiz program bu sayfanın sonunda bulunabilir, kod da tüm gerekli dosyalarla buradan indirilebilir. Bu bölümde programın arkasındaki mantığı tartışacağız. Program, Robotik Kolu kontrol etmek için ADC modülünü, Zamanlayıcı Modülünü ve LCD Modülünü kullanır. ADC özelliklerini veya Zamanlayıcı özelliklerini nasıl kullanacağınızı veya bir LCD ile PIC arayüzünü nasıl kullanacağınızı bilmiyorsanız, bunları öğrenmek için ilgili bağlantılara geri dönebilirsiniz. Aşağıdaki açıklama, okuyucunun bu kavramlara aşina olduğu varsayılarak verilmiştir.
Zamanlayıcı 0 Bağlantı Noktası Yapılandırması
Koddaki en önemli bölüm , Zamanlayıcı 0'ı her belirli gecikme için aşırı akışa ayarlamaktır. Bu gecikmeyi hesaplayacak formüller şu şekilde verilebilir:
Gecikme = ((256-REG_val) * (Prescal * 4)) / Fosc
OPTION_REG ve TMR0 yazmacını kullanarak, Timer 0'ı 32'lik bir prescalar değerle çalışacak şekilde ayarladık ve REG değeri 248'e ayarlandı. Donanımımızda kullanılan kristal frekansı (Fosc) 20Mhz'dir. Bu değerlerle gecikme şu şekilde hesaplanabilir:
Gecikme = ((256-248) * (32 * 4)) / (20000000) = 0.0000512 saniye (veya) = 0.05 msn
Şimdi zamanlayıcıyı her 0.05 ms'de bir taşacak şekilde ayarladık. Aynısını yapmak için kod aşağıda verilmiştir.
/ ***** Zamanlayıcı için Bağlantı Noktası Yapılandırması ****** / OPTION_REG = 0b00000100; // Harici frekansı olan Timer0 ve prescalar olarak 32 // Ayrıca PULL UP'ları Etkinleştirir TMR0 = 248; // 0.0001s için zaman değerini yükle; delayValue yalnızca 0-256 arasında olabilir TMR0IE = 1; // PIE1 kaydında zamanlayıcı kesinti bitini etkinleştir GIE = 1; // Global Kesmeyi Etkinleştir PEIE = 1; // Çevre Birimi Kesmesini Etkinleştir / *********** ______ *********** /
Servo motorun toplam 0ms - 2ms kontrol penceresinden 0.05msn'lik bir çözünürlükle kontrol edebiliriz, bu da motor için 0 derece ile 180 derece arasında (2 / 0.05) 40 farklı pozisyona sahip olmamızı sağlar. MCU'nuz daha fazla konum ve hassas kontrol elde etmek için onu destekleyebilirse, bu değeri daha da azaltabilirsiniz.
Kesinti Servis Rutini (ISR)
Artık Zamanlayıcı 0'ı her 0.05 ms için aşırı akışa ayarladığımıza göre, TMR0IF kesinti bayrağını 0.05 ms olarak ayarlayacağız. Yani ISR işlevi içinde biz bu bayrağı sıfırlayabilirsiniz ve değişken denilen sayısını artırmaz tarafından biri. Şimdi bu değişken her 0.05 ms için 1 artacaktır.
void interrupt timer_isr () { if (TMR0IF == 1) // Zamanlayıcı aşımı nedeniyle zamanlayıcı bayrağı tetiklendi -> her 0.05 ms için taşmaya ayarlandı { TMR0 = 248; // Zamanlayıcı Değerini Yükle TMR0IF = 0; // timer interrupt flag sayımını temizle ++; // Her 0,05 ms için artışları 1 olarak sayın }
Görev Döngüsü ve Zamanında Hesaplama
Daha sonra, beş servo motorun tümü için görev döngüsünü ve çalışma süresini hesaplamamız gerekiyor. Her biri kolun ayrı bölümünü kontrol etmek için kullanılan beş servo motorumuz var. Bu yüzden beşinin de ADC değerini okumalı ve her biri için görev döngüsünü ve zamanında hesaplamalıyız.
ADC değeri, elde edilen değer ile 0,0976 (100/1024 = 0,0976) çarpılarak% 0 ila% 100 görev döngüsüne dönüştürülebilen 0 ila 1024 aralığında olacaktır. Bu% 0 ila% 100 görev döngüsü daha sonra AÇIK zamana dönüştürülmelidir. % 100 görev döngüsünde AÇIK süresinin 2 ms (180 derece için) olması gerektiğini biliyoruz, bu nedenle 0,02 (2/100 = 0,02) ile çarpmanın 0 ila 100 görev döngüsünü 0 ila 2 ms'ye dönüştürecektir. Ama sonra zamanlayıcı değişken sayımız her 0.05 ms'de bir artacak şekilde ayarlandı. Bu sayım değerinin her 1 ms için 20 (1 / 0.05 = 20) olacağı anlamına gelir. Öyleyse, bize 0,4 (0,02 * 20 = 0,4) değerini verecek olan programımızın tam çalışma süresini hesaplamak için 20'yi 0,02 ile çarpmalıyız. Aynı kod aşağıda gösterilmiştir, bir for döngüsü kullanarak 5 potun tümü için 5 kez tekrarlandığını görebilirsiniz. Elde edilen değerler T_ON dizisinde saklanır.
for (int pot_num = 0; pot_num <= 3; pot_num ++) { int Pev_val = T_ON; POT_val = (ADC_Read (pot_num)); // ADC Duty_cycle = (POT_val * 0.0976) kullanarak POT değerini okuyun ; // 0 ila 1024 ila 0 ila 100 T_ON = Duty_cycle * 0.4; // 20 * 0.02
Hangi motorun döndürüleceğini seçme
ISR kodunu tüm mikro denetleyiciyi yavaşlatacak şekilde ağır hale getireceğinden, beş motoru birlikte kontrol edemiyoruz. Yani aynı anda yalnızca bir servo motoru döndürmemiz gerekiyor. Hangi servonun döndürüleceğini seçmek için, mikro denetleyicinin beş servo motorun da ON süresini izler ve bunu önceki çalışma süresiyle karşılaştırır. ON süresinde bir değişiklik varsa, o zaman belirli servonun taşınması gerektiği sonucuna varabiliriz. Aynı kod aşağıda gösterilmiştir.
eğer (T_ON! = Pev_val) { Lcd_Clear (); servo = pot_num; Lcd_Set_Cursor (2,11); Lcd_Print_String ("S:"); Lcd_Print_Char (servo + '0'); eğer (pot_num == 0) {Lcd_Set_Cursor (1,1); Lcd_Print_String ("A:");} else if (pot_num == 1) {Lcd_Set_Cursor (1,6); Lcd_Print_String ("B:");} else if (pot_num == 2) {Lcd_Set_Cursor (1,11); Lcd_Print_String ("C:");} else if (pot_num == 3) {Lcd_Set_Cursor (2,1); Lcd_Print_String ("D:");} else if (pot_num == 4) {Lcd_Set_Cursor (2,6); Lcd_Print_String ("E:");} char d2 = (Duty_cycle)% 10; char d1 = (Görev_döngüsü / 10)% 10; Lcd_Print_Char (d1 + '0'); Lcd_Print_Char (d2 + '0');
Ayrıca servo görev döngüsünü LCD ekranda yazdırıyoruz, böylece kullanıcı mevcut konumdan haberdar olabilir. AÇIK süresindeki değişime bağlı olarak değişken servo, her biri ayrı motorları temsil eden 0 ile 4 arasındaki sayılarla güncellenir.
ISR içindeki Servo Motorun Kontrol Edilmesi
ISR'nin içinde her 0.05 ms için artan değişken sayımız var, bu, her 1 ms için değişkenin 20 artacağı anlamına geliyor. Bunu kullanarak, PWM sinyali üretmek için pimleri kontrol etmeliyiz. Sayma değeri çalışma süresinden azsa, o motorun GPIO'su aşağıdaki satır kullanılarak açılır.
PORTD = PORTD - servo_code;
Burada servo kodu dizisi, beş servo motorun tümünün pin detayına sahiptir ve değişken servodaki değere bağlı olarak, söz konusu servo motorun kodu kullanılacaktır. Daha sonra mantıksal olarak VEYA (-) mevcut PORTD bitleri ile olur, böylece diğer motorun değerlerini bozmaz ve yalnızca bu belirli motoru güncelleriz. Benzer şekilde pimi kapatmak için
PORTD = PORTD & ~ (servo_code);
Mantık ters (~) operatörünü kullanarak bit değerini tersine çevirdik ve ardından diğer pinleri önceki durumlarında bırakırken sadece istenen pini kapatmak için PORTD üzerinde bir AND (&) işlemi gerçekleştirdik. Kod parçacığının tamamı aşağıda gösterilmiştir.
void interrupt timer_isr () { if (TMR0IF == 1) // Zamanlayıcı aşımı nedeniyle zamanlayıcı bayrağı tetiklendi -> her 0.05 ms için taşmaya ayarlandı { TMR0 = 248; // Zamanlayıcı Değerini Yükle TMR0IF = 0; // timer interrupt flag sayımını temizle ++; // Her 0,05 ms için 1 artış -> sayı her 1 ms için 20 olacaktır (0,05 / 1 = 20) } int servo_code = {0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100}; eğer (sayı> = 20 * 20) sayı = 0; eğer (sayım <= (T_ON)) PORTD = PORTD - servo_code; başka PORTD = PORTD & ~ (servo_code); }
GPIO pini tekrar açılmadan önce toplam döngünün 20 ms sürmesi gerektiğini biliyoruz. Bu yüzden sayımın değerini 400 ile karşılaştırarak sayının 20 ms'yi aşıp aşmadığını kontrol ederiz (yukarıda tartışılan hesaplamanın aynısı) ve eğer evet ise sayımı yeniden sıfırlamak zorundayız.
PIC Robotik Kol Kodunun Simülasyonu
Kodu gerçek donanıma götürmeden önce simüle etmek her zaman daha iyidir. Bu yüzden, kodumu simüle etmek için Proteus'u kullandım ve doğru çalıştığını doğruladım. Simülasyon için kullanılan devre aşağıda gösterilmiştir, PWM sinyallerinin gerektiği gibi üretilip üretilmediğini kontrol etmek için bir osiloskop kullandık. Ayrıca LCD ve Servo motorların beklendiği gibi dönüp dönmediğini de doğrulayabiliriz.
Gördüğünüz gibi LCD, 3. motor olan pot değerine göre D motorunun görev döngüsünü 07 olarak gösteriyor. Benzer şekilde, başka bir kap hareket ettirilirse, o kabın görev döngüsü ve motor numarası LCD'de görüntülenecektir. Osiloskopta gösterilen PWM sinyali aşağıda gösterilmiştir.
Toplam döngü süresi, istenen 20 ms'ye çok yakın olan osiloskop üzerindeki imleç seçeneği kullanılarak 22,2 ms olarak ölçülür. Son olarak, kodun çalıştığından eminiz, bu nedenle devre ile devam etmek için onu bir perf kart üzerinde lehimleyebilir veya bir PCB kullanabiliriz. Devre tahtasında kolayca çalışmayacaktır çünkü POT her zaman zayıf bağlantılar nedeniyle bazı problemler yaratma eğilimindedir.
EasyEDA kullanarak PCB Tasarımı
Bu PIC Robotik Kolunu tasarlamak için EasyEDA adlı çevrimiçi EDA aracını seçtik. Uzun zamandır kullanıyorum ve geniş yer kaplaması ve kullanımı kolay doğası nedeniyle çok uygun buluyorum. PCB'yi tasarladıktan sonra, PCB numunelerini düşük maliyetli PCB üretim hizmetleri ile sipariş edebiliriz. Ayrıca, geniş bir elektronik bileşen stoğuna sahip oldukları ve kullanıcıların PCB siparişiyle birlikte gerekli bileşenleri sipariş edebilecekleri bileşen tedarik hizmeti de sunarlar.
Devrelerinizi ve PCB'lerinizi tasarlarken, devre ve PCB tasarımlarınızı herkese açık hale getirebilirsiniz, böylece diğer kullanıcılar bunları kopyalayabilir veya düzenleyebilir ve işinizden faydalanabilir, ayrıca tüm Devre ve PCB düzenlerimizi bu devre için halka açık hale getirdik, kontrol edin aşağıdaki bağlantı:
easyeda.com/circuitdigest/pic-development-board-for-robotic-arm
Bu bağlantıyı kullanarak, bu projede kullandığımız aynı PCB'yi doğrudan sipariş edebilir ve kullanabilirsiniz. Tasarım tamamlandıktan sonra pano, üretimden sonra panonun nasıl görüneceğini görselleştirmede çok yardımcı olacak 3D model olarak görülebilir. Kullandığımız kartın 3 boyutlu modeli aşağıda gösterilmiştir. Bunun dışında kaygan ekranın beklendiği gibi olup olmadığını kontrol etmek için panonun üst ve alt katmanını da görüntüleyebilirsiniz.
Çevrimiçi Numune Hesaplama ve Sipariş Etme
Bu PIC Robot PCB'nin tasarımını tamamladıktan sonra PCB'yi JLCPCB.com aracılığıyla sipariş edebilirsiniz. PCB'yi JLCPCB'den sipariş etmek için Gerber Dosyasına ihtiyacınız var. PCB'nize Gerber dosyaları indirmek için hemen tıklayın üret Fabrikasyon Dosyası EasyEDA editör sayfasında düğmesini, sonra oradan Gerber dosyasını indirmenizi veya tıklayabilir JLCPCB en Sipariş aşağıdaki resimde gösterildiği gibi. Bu sizi, sipariş etmek istediğiniz PCB sayısını, kaç tane bakır katmanına ihtiyacınız olduğunu, PCB kalınlığını, bakır ağırlığını ve hatta aşağıda gösterilen anlık görüntü gibi PCB rengini seçebileceğiniz JLCPCB.com'a yönlendirecektir:
Tüm seçenekleri seçtikten sonra, "Sepete Kaydet" e tıklayın ve ardından EasyEDA'dan indirdiğimiz Gerber Dosyanızı yükleyebileceğiniz sayfaya yönlendirileceksiniz. Gerber dosyanızı yükleyin ve "Sepete Kaydet" i tıklayın. Son olarak, siparişinizi tamamlamak için Güvenli Ödeme'ye tıklayın, ardından PCB'lerinizi birkaç gün sonra alacaksınız. PCB'yi 2 $ olan çok düşük bir oranda imal ediyorlar. Yapım süreleri de çok daha azdır, bu da 3-5 günlük DHL teslimatıyla 48 saattir, temelde PCB'lerinizi siparişinizi verdikten sonraki bir hafta içinde alacaksınız.
PCB sipariş sonra şunları yapabilirsiniz kontrol Üretim İlerleme sizin PCB tarih ve saat ile. Hesap sayfasına gidip "Üretim İlerlemesi" ni tıklayarak kontrol edin.
PCB'leri sipariş ettikten birkaç gün sonra PCB numunelerini aşağıdaki resimlerde gösterildiği gibi güzel ambalajlarda aldım.
Ve bu parçaları aldıktan sonra gerekli tüm bileşenleri PCB üzerine lehimledim. Ayrıca bağlantı tellerini kullanmak yerine doğrudan POT'u doğrudan lehimledim çünkü başlangıçta kullandığım dişi-dişi teller muhtemelen gevşek kontaklar nedeniyle garip analog çıkış voltajları verirken. Tüm bileşenler birleştirildikten sonra PCB'm böyle bir şeye benziyordu.
Bu kartta yalnızca bir 7805 olduğunu fark etmiş olabilirsiniz. Bunun nedeni, başlangıçta hem PIC hem de servo motora güç sağlamak için sadece regülatörden kurtulabileceğimi düşündüm ve daha sonra ikiye ihtiyacım olduğunu fark ettim. Bu yüzden, servo motorları burada gördüğünüz yeşil kablolarla çalıştırmak için harici bir devre kullandım.
Yine de bunun için endişelenmenize gerek yok çünkü; Şimdi PCB'de değişiklikler yaptım. Modifiye edilmiş PCB'yi kullanabilir ve kart üzerindeki her iki regülatörü lehimleyebilirsiniz.
PIC Robotik Kolun Çalışması
Tüm yorucu işlerden sonra, ödeme zamanı. Karttaki tüm bileşenleri lehimleyin ve programı PIC denetleyicisine yükleyin. Tam Kod aşağıda verilmiştir veya buradan indirilebilir. Tahtada sağlanan programlama konektörü, programı Pickit 3 kullanarak çok fazla güçlük çekmeden doğrudan yüklemenize yardımcı olacaktır. Program yüklendikten sonra, şu anda kontrol edilmekte olan servoyu gösteren LCD'yi görmelisiniz. PIC Mikrodenetleyiciyi programlama hakkında daha fazla bilgi edinmek için önceki öğreticiyi izlemeniz yeterlidir.
Oradan basitçe potu çevirebilir ve servo motorların her potansiyometreye nasıl tepki verdiğini kontrol edebilirsiniz. Formatı anladıktan sonra, gerçekleştirmek ve eğlenmek için ihtiyacınız olan eylemi gerçekleştirmek için robotik kolu kontrol edebilirsiniz. Aşağıda bağlantısı verilen videoda projenin eksiksiz çalışmasını bulabilirsiniz.
Bu, projeyi anladığınızı ve ondan yeni bir şey öğrendiğinizi umuyorlar. Herhangi bir sorunuz varsa yorum bölümüne bırakın veya diğer teknik tartışmalar için forumları kullanın.