- Електрическа схема
- Генериране на PWM сигнали на GPIO щифт за управление на серво мотора
- Програмиране PIC16F8771A за роботизирана ръка
- Симулация на PIC Robotic Arm Code
- Дизайн на печатни платки с помощта на EasyEDA
- Изчисляване и поръчване на проби онлайн
- Работа на PIC Robotic Arm
От поточната линия на автомобилната индустрия до роботите за телехирургия в космоса, Robotic Arms могат да бъдат намерени навсякъде. Механизмите на тези роботи са подобни на човешки, който може да бъде програмиран за подобна функция и увеличени възможности. Те могат да се използват за извършване на повтарящи се действия по-бързо и точно от хората или могат да се използват в сурови условия, без да рискуват човешкия живот. Вече създадохме Record and Play Robotic Arm, използвайки Arduino, който може да бъде обучен да изпълнява определена задача и да бъде повтарян завинаги.
В този урок ще използваме индустриалния стандарт 8-битов микроконтролер PIC16F877A, за да управляваме същото роботизирано рамо с потенциометри. Предизвикателството с този проект е, че PIC16F877A има само два щифта с възможност за PWN, но ние трябва да контролираме около 5 серво мотора за нашия робот, който изисква 5 отделни PWM щифта. Така че трябва да използваме GPIO пиновете и да генерираме PWM сигнали на PIC GPIO пиновете, използвайки таймерните прекъсвания. Сега, разбира се, бихме могли да надстроим до по-добър микроконтролер или да използваме IC за демултиплексор, за да улесним нещата тук. Но все пак си струва да опитате този проект за учебния опит.
Механичната структура на роботизираното рамо, което използвам в този проект, беше изцяло 3D отпечатана за предишния ми проект; можете да намерите пълните дизайнерски файлове и процедурата за сглобяване тук. Като алтернатива, ако нямате 3D принтер, можете да създадете и просто роботизирано рамо, използвайки картони, както е показано в връзката. Ако приемем, че по някакъв начин сте се сдобили с вашето роботизирано рамо, нека продължим към проекта.
Електрическа схема
Пълната схема на веригата за това роботизирано рамо на базата на PIC микроконтролер е показана по-долу. Схемите са начертани с помощта на EasyEDA.
Схемата е доста проста; целият проект се захранва от 12V адаптер. След това тези 12V се преобразуват в + 5V с помощта на два регулатора на напрежение 7805. Единият е означен като + 5V, а другият е означен като + 5V (2). Причината за наличието на два регулатора е, че когато серво серво се върти, той вкарва много ток, което създава спад на напрежението. Този спад на напрежението принуждава PIC да се рестартира, поради което не можем да управляваме както PIC, така и сервомоторите на една и съща + 5V релса. Така че този, означен като + 5V, се използва за захранване на микроконтролера PIC, LCD и потенциометрите, а отделен изход на регулатора, обозначен като + 5V (2), се използва за захранване на серво мотори.
Петте изходни щифта на потенциометрите, които осигуряват променливо напрежение от 0V до 5V, са свързани към аналоговите щифтове An0 до AN4 на PIC. Тъй като планираме да използваме таймери за генериране на ШИМ, сервомоторите могат да бъдат свързани към всеки GPIO пин. Избрах щифтове от RD2 до RD6 за серво мотори, но това може да бъде всеки GPIO по ваш избор.
Тъй като програмата включва много отстраняване на грешки, 16x2 LCD дисплей също е свързан към portB на PIC. Това ще покаже работния цикъл на сервомоторите, които се контролират. Отделно от това имам и разширени връзки за всички GPIO и аналогови щифтове, за всеки случай, ако в бъдеще трябва да се свържат сензори. И накрая, аз също свързах програмист ПИН H1 за директно програмиране на PIC с pickit3, използвайки опцията за програмиране ICSP.
Генериране на PWM сигнали на GPIO щифт за управление на серво мотора
След като веригата е готова, трябва да разберем как да генерираме PWN сигнали на GPIO щифта на PIC за управление на серво мотора. Вече уморихме нещо подобно, използвайки метода за прекъсване на таймера, и успяхме. Тук просто ще надградим върху него, така че ако сте нов тук, силно ви препоръчвам да прочетете този предишен урок, преди да продължите по-нататък.
Всички хоби серво мотори работят с честота 50Hz. Това означава, че един пълен импулсен цикъл за серво мотор ще бъде 1/50 (F = 1 / T), което е 20ms. От тези пълни 20ms управляващият сигнал е само от 0 до 2ms, докато останалата част от сигнала винаги е изключена. Фигурата по-долу показва как времето за включване варира само от 0 до 2 ms за завъртане на двигателя от 0 градуса до 180 градуса от общата продължителност от 20 ms.
Имайки предвид това, ние трябва да напишем програмата по такъв начин, че PIC да отчита от 0 до 1204 от потенциометъра и да го преобразува на 0 до 100, което ще бъде работният цикъл на серво мотора. Използвайки този работен цикъл, можем да изчислим времето за включване на серво мотора. След това можем да инициализираме прекъсването на таймера, за да се препълни с редовен интервал, така че да действа подобно на функцията millis () в Arduino. С това можем да превключим статуса GPIO щифт на висок за желаната продължителност и да го изключим след 20 ms (един пълен цикъл) и след това да повторим същия процес. Сега, след като разбрахме логиката, нека влезем в програмата.
Програмиране PIC16F8771A за роботизирана ръка
Както винаги пълната програма с видео може да бъде намерена в края на тази страница, кодът също може да бъде изтеглен от тук с всички необходими файлове. В този раздел ще обсъдим логиката на програмата. Програмата използва ADC модул, таймер и LCD модул за управление на роботизираното рамо. Ако не сте наясно как да използвате функциите на ADC или таймера или да свържете LCD с PIC, тогава можете да се върнете към съответните връзки, за да ги научите. Обяснението по-долу е дадено, ако читателят е запознат с тези понятия.
Таймер 0 Конфигурация на порта
Най-важният раздел в кода е настройването на таймера 0 на претоварване за всяко конкретно забавяне. Формулите за изчисляване на това закъснение могат да бъдат дадени като
Забавяне = ((256-REG_val) * (Prescal * 4)) / Fosc
Чрез използването на регистъра OPTION_REG и TMR0 сме настроили таймера 0 да работи с прескаларна стойност 32 и REG val е настроен на 248. Използваната в нашия хардуер кристална честота (Fosc) е 20Mhz. С тези стойности закъснението може да се изчисли като
Забавяне = ((256-248) * (32 * 4)) / (20000000) = 0,0000512 секунди (или) = 0,05 мсек
Така че сега сме настроили таймера да прелива на всеки 0,05ms. Кодът да се направи същото е даден по-долу
/ ***** Конфигурация на порт за таймер ****** / OPTION_REG = 0b00000100; // Timer0 с външна честота и 32 като прескаларна // Също така позволява PULL UPs TMR0 = 248; // Зареждане на времевата стойност за 0,0001s; delayValue може да бъде между 0-256 само TMR0IE = 1; // Активиране на бит за прекъсване на таймера в регистър PIE1 GIE = 1; // Активиране на глобално прекъсване PEIE = 1; // Активиране на периферното прекъсване / *********** ______ *********** /
От общия прозорец за управление от 0ms до 2ms на сервомотора можем да го управляваме с резолюция от 0,05msec, което ни позволява да имаме (2 / 0,05) 40 различни позиции за двигателя между 0 градуса до 180 градуса. Можете да намалите тази стойност допълнително, ако вашият MCU може да го поддържа, за да получи повече позиции и прецизен контрол.
Рутинна услуга за прекъсване (ISR)
Сега, когато имаме таймер 0, настроен на преливане за всеки 0,05 ms, ще имаме флаг за прекъсване TMR0IF за 0,05 ms. Така че вътре в функцията ISR можем да нулираме този флаг и да увеличим променлива, наречена count с единица. Така че сега тази променлива ще се увеличи с 1 за всеки 0,05ms.
void interrupt timer_isr () { if (TMR0IF == 1) // Знамето на таймера е задействано поради препълване на таймера -> зададено за препълване на всеки 0,05 ms { TMR0 = 248; // Зареждане на стойността на таймера TMR0IF = 0; // Изчистване на броя на флаговете за прекъсване на таймера ++; // Брой стъпки с 1 за всеки 0,05ms }
Изчисляване на работния цикъл и на времето
След това трябва да изчислим работния цикъл и навреме за всичките пет серво мотора. Разполагаме с пет серво мотора, всеки от които се използва за управление на отделна секция на рамото. Затова трябва да прочетем стойността на ADC на всичките пет и да изчислим работния цикъл и навреме за всеки.
Стойността на ADC ще бъде в диапазона от 0 до 1024, което може да бъде преобразувано в 0% до 100% работен цикъл чрез просто умножаване на 0,0976 (100/1024 = 0,0976) до получената стойност. След това този от 0 до 100% работен цикъл трябва да бъде преобразуван във време за включване. Знаем, че при 100% работен цикъл времето за включване трябва да бъде 2ms (за 180 градуса), така че умножаването на 0,02 (2/100 = 0,02) ще превърне 0 до 100 работен цикъл на 0 до 2ms. Но тогава броят на нашите таймерни променливи е настроен да се увеличава веднъж на всеки 0,05 ms. Това означава, че стойността на броя ще бъде 20 (1 / 0,05 = 20) за всеки 1ms. Така че трябва да умножим 20 с 0,02, за да изчислим точното време за нашата програма, което ще ни даде стойността 0,4 (0,02 * 20 = 0,4). Кодът за същото е показан по-долу, можете да го видите да се повтаря 5 пъти за всички 5 пота, използвайки цикъл for. Получените стойности се съхраняват в масива T_ON.
за (int pot_num = 0; pot_num <= 3; pot_num ++) { int Pev_val = T_ON; POT_val = (ADC_Read (pot_num)); // Прочетете стойността на POT, използвайки ADC Duty_cycle = (POT_val * 0.0976); // Карта 0 до 1024 до 0 до 100 T_ON = Duty_cycle * 0,4; // 20 * 0,02
Избор на кой двигател да се върти
Не можем да управляваме всичките пет двигателя заедно, тъй като това ще накара ISR кода да забави целия микроконтролер. Така че трябва да въртим само един серво мотор наведнъж. За да изберете кой серво да въртите, микроконтролерът следи времето за включване на всичките пет серво мотора и го сравнява с предишния навреме. Ако има промяна във времето за включване, тогава можем да заключим, че конкретният серво трябва да бъде преместен. Кодът за същото е показан по-долу.
ако (T_ON! = Pev_val) { Lcd_Clear (); серво = номер_пот; Lcd_Set_Cursor (2,11); Lcd_Print_String ("S:"); Lcd_Print_Char (серво + '0'); if (pot_num == 0) {Lcd_Set_Cursor (1,1); Lcd_Print_String ("A:");} иначе ако (pot_num == 1) {Lcd_Set_Cursor (1,6); Lcd_Print_String ("B:");} иначе ако (pot_num == 2) {Lcd_Set_Cursor (1,11); Lcd_Print_String ("C:");} иначе ако (pot_num == 3) {Lcd_Set_Cursor (2,1); Lcd_Print_String ("D:");} иначе ако (pot_num == 4) {Lcd_Set_Cursor (2,6); Lcd_Print_String ("E:");} char d2 = (Duty_cycle)% 10; char d1 = (Duty_cycle / 10)% 10; Lcd_Print_Char (d1 + '0'); Lcd_Print_Char (d2 + '0');
Също така отпечатваме цикъла на задвижване на серво на LCD екрана, за да може потребителят да знае текущото му положение. Въз основа на промяната във времето за включване променливият сервопривод се актуализира с числа от 0 до 4, всеки представляващ отделни двигатели.
Управление на сервомотора в ISR
Вътре в ISR имаме броя на променливите, който се увеличава на всеки 0,05 ms, това означава, че на всеки 1 ms променливата ще бъде увеличена с 20. Използвайки това, ние трябва да контролираме щифтовете, за да произведем PWM сигнал. Ако стойността на броя е по-малка от времето за включване, тогава GPIO на този двигател се включва, използвайки долния ред
PORTD = PORTD - servo_code;
Тук масивът servo_code има подробности за пина на всичките пет сервомотора и въз основа на стойността в променлива серво, ще се използва кодът за този конкретен серво мотор. Тогава е логично ИЛИ (-) със съществуващите PORTD битове, така че да не нарушаваме стойностите на другия двигател и да актуализираме само този конкретен двигател. По същия начин за изключване на щифта
PORTD = PORTD & ~ (серво_код);
Обърнахме битовата стойност, използвайки логическия инверсен (~) оператор и след това извършихме операция И (&) на PORTD, за да изключим само желания щифт, като оставихме останалите пинове в предишното им състояние. Пълният кодов фрагмент е показан по-долу.
void interrupt timer_isr () { if (TMR0IF == 1) // Знамето на таймера е задействано поради препълване на таймера -> зададено за препълване за всеки 0,05 ms { TMR0 = 248; // Зареждане на стойността на таймера TMR0IF = 0; // Изчистване на броя на флаговете за прекъсване на таймера ++; // Брой стъпки с 1 за всеки 0,05 ms -> броят ще бъде 20 за всеки 1 ms (0,05 / 1 = 20)) } int servo_code = {0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100}; ако (брой> = 20 * 20) брой = 0; if (count <= (T_ON)) PORTD = PORTD - servo_code; else PORTD = PORTD & ~ (servo_code); }
Знаем, че общият цикъл трябва да продължи 20 ms, преди GPIO щифтът да се включи отново. Така че проверяваме дали броят е надвишил 20ms, като сравним стойността на count с 400 (същото изчисление, както е обсъдено по-горе) и ако да, трябва да инициализираме броя, за да бъде отново нула.
Симулация на PIC Robotic Arm Code
Винаги е по-добре да симулирате кода, преди да го занесете на истинския хардуер. Затова използвах Proteus, за да симулирам кода си и го проверих, за да работи правилно. Схемата, използвана за симулация, е показана по-долу. Използвахме осцилоскоп, за да проверим дали PWM сигналите се генерират според изискванията. Също така можем да проверим дали LCD и серво моторите се въртят според очакванията.
Както можете да видите, LCD показва работния цикъл на мотора D да бъде 07 въз основа на стойността на гърнето, която е 3 -ти мотор. Подобно, ако друг пот се премести, работният цикъл на този пот и неговият номер на двигателя ще се покаже на LCD. ШИМ сигналът, показан на осцилоскопа, е показан по-долу.
Общият период на цикъла се измерва на 22,2 ms, като се използва опцията за курсор на осцилоскопа, която е много близка до желаните 20 ms. Накрая сме сигурни, че кодът работи, така че за да продължим с веригата, можем или да го запоим на перфектна платка, или да използваме печатни платки. Той няма да работи лесно на макет, защото POT винаги има тенденция да създава някои проблеми поради лоши връзки.
Дизайн на печатни платки с помощта на EasyEDA
За да проектираме тази роботизирана ръка PIC, ние избрахме онлайн инструмента за EDA, наречен EasyEDA. Използвам го отдавна и го намирам за много удобен поради огромното му наличие на отпечатък и лесна за използване природа. След проектирането на печатни платки, ние можем да поръчаме пробите на печатни платки чрез техните евтини услуги за производство на печатни платки. Те също така предлагат услуга за снабдяване с компоненти, когато имат голям запас от електронни компоненти и потребителите могат да поръчат необходимите им компоненти заедно с поръчката на печатни платки.
Докато проектирате вашите схеми и печатни платки, можете също така да направите вашите схеми и печатни платки публични, така че другите потребители да могат да ги копират или редактират и да се възползват от вашата работа, ние също направихме цялата ни схема на платки и печатни платки публична за тази схема, проверете връзката по-долу:
easyeda.com/circuitdigest/pic-development-board-for-robotic-arm
Използвайки тази връзка, можете директно да поръчате същата PCB, която използваме в този проект, и да я използвате. След като дизайнът завърши, дъската може да се разглежда като 3D модел, който ще бъде много полезен при визуализирането на това как ще изглежда дъската след изработката. 3D моделът на дъската, който използваме, е показан по-долу. Освен това можете също да видите горния и долния слой на дъската, за да проверите дали хлъзгавият екран е както се очаква.
Изчисляване и поръчване на проби онлайн
След като завършите дизайна на тази PIC Robot PCB, можете да поръчате PCB чрез JLCPCB.com. За да поръчате печатната платка от JLCPCB, ви е необходим Gerber File. За да изтеглите Gerber файлове от вашата PCB, просто щракнете върху бутона Generate Fabrication File на страницата на редактора EasyEDA, след това изтеглете Gerber файла от там или можете да кликнете върху Order в JLCPCB, както е показано на изображението по-долу. Това ще ви пренасочи към JLCPCB.com, където можете да изберете броя на печатни платки, които искате да поръчате, колко медни слоя ви трябват, дебелината на печатната платка, теглото на медта и дори цвета на печатната платка, като снимката, показана по-долу:
След като сте избрали всички опции, щракнете върху „Запазване в кошницата“ и след това ще бъдете отведени до страницата, където можете да качите вашия Gerber файл, който сме изтеглили от EasyEDA. Качете вашия Gerber файл и кликнете върху „Запазване в кошницата“. И накрая кликнете върху Checkout Secure, за да завършите поръчката си, след което ще получите вашите PCB няколко дни по-късно. Те произвеждат печатната платка на много ниска цена, която е 2 долара. Времето им за изграждане също е много по-малко, което е 48 часа с DHL доставка от 3-5 дни, като основно ще получите вашите печатни платки в рамките на една седмица след поръчката.
След като поръчате печатната платка, можете да проверите производствения напредък на вашата печатна платка с дата и час. Проверявате го, като отидете на страницата на акаунта и кликнете върху „Напредък на производството“.
След няколко дни поръчка на печатни платки взех пробите на печатни платки в хубава опаковка, както е показано на снимките по-долу.
И след получаването на тези парчета съм запоил всички необходими компоненти върху печатната платка. Също така директно запоях POT директно, вместо да използвам свързващи проводници, защото женските към женските проводници, които първоначално използвах, когато дадоха странни аналогови изходни напрежения, вероятно поради разхлабени контакти. След като всички компоненти бяха сглобени, моята PCB изглеждаше нещо подобно.
Може би сте забелязали, че на тази дъска има само един 7805. Това е така, защото първоначално мислех, че мога да се измъкна само с регулатор за захранване както на PIC, така и на серво мотор, а по-късно осъзнах, че имам нужда от два. Затова използвах външна верига за захранване на сервомоторите през зелените проводници, които виждате тук.
Въпреки това не е нужно да се притеснявате много за това, защото; Направих промените в печатната платка сега. Можете да използвате модифицираната печатна платка и да запоявате и двата регулатора на самия борд.
Работа на PIC Robotic Arm
След цялата уморителна работа е време за изплащане. Спойте всички компоненти на платката и качете програмата на PIC контролера. Пълният код е даден по-долу или може да бъде изтеглен от тук. Конекторът за програмиране, предоставен на платката, трябва да ви помогне да качите програмата директно с помощта на Pickit 3, без много да се затруднявате. След като програмата бъде качена, трябва да видите LCD дисплея, показващ серво, който в момента се контролира. За да научите повече за програмирането на PIC Microcontroller, просто следвайте предишния урок.
Оттам можете просто да завъртите гърнето и да проверите как сервомоторите реагират на всеки потенциометър. След като разберете формата, можете да контролирате роботизираната ръка, за да извършите каквото и да е действие, което ви е необходимо, за да се забавлявате. Можете да намерите пълната работа на проекта във видеото, свързано по-долу.
Това е, момчета, надявате се, че сте разбрали проекта и сте научили нещо ново от него. Ако имате въпроси, оставете ги в раздела за коментари или използвайте форумите за други технически дискусии.