- Esquema de connexions
- Generació de senyals PWM al pin GPIO per al Servo Motor Control
- Programació PIC16F8771A per a Robotic Arm
- Simulació del codi de braç robòtic PIC
- Disseny de PCB amb EasyEDA
- Càlcul i ordenació de mostres en línia
- Funcionament del braç robòtic PIC
Des de la línia de muntatge de les indústries de fabricació d’automòbils fins als robots de telesurgia a l’espai, Robotic Arms es troba a tot arreu. Els mecanismes d’aquests robots són similars als humans que es poden programar per a funcions similars i capacitats augmentades. Es poden utilitzar per realitzar accions repetides amb més rapidesa i precisió que els humans o es poden utilitzar en entorns difícils sense arriscar la vida humana. Ja hem construït un braç robòtic Record and Play amb Arduino que es podria entrenar per fer una tasca particular i fer-lo repetir per sempre.
En aquest tutorial utilitzarem el microcontrolador de 8 bits PIC16F877A estàndard de la indústria per controlar el mateix braç robotitzat amb potenciòmetres. El repte d’aquest projecte és que PIC16F877A només té dos pins compatibles amb PWN, però hem de controlar uns 5 servomotors per al nostre robot que requereix 5 pins PWM individuals. Per tant, hem d’utilitzar els pins GPIO i generar senyals PWM als pins GPIO PIC mitjançant les interrupcions del temporitzador. Ara, per descomptat, podríem actualitzar a un microcontrolador millor o utilitzar un IC de multiplexor per fer les coses molt més fàcils aquí. Però, tot i així, val la pena provar aquest projecte amb l’experiència d’aprenentatge.
L’estructura mecànica del braç robòtic que estic fent servir en aquest projecte es va imprimir completament en 3D per al meu projecte anterior; aquí podeu trobar els fitxers de disseny i el procediment de muntatge complets. Com a alternativa, si no teniu una impressora 3D, també podeu crear un braç robòtic senzill mitjançant cartrons, tal com es mostra a l’enllaç. Suposant que d'alguna manera heu aconseguit el braç robotitzat, podeu continuar amb el projecte.
Esquema de connexions
A continuació es mostra el diagrama de circuits complet d’aquest braç robòtic basat en microcontrolador PIC. Els esquemes es van dibuixar amb EasyEDA.

El diagrama del circuit és força senzill; el projecte complet és alimentat per l'adaptador de 12V. A continuació, aquest 12V es converteix a + 5V mitjançant dos reguladors de voltatge 7805. Un s’etiqueta com a + 5V i l’altre s’etiqueta com a + 5V (2). La raó de tenir dos reguladors és que quan el servo gira, entra molta corrent, cosa que crea una caiguda de tensió. Aquesta caiguda de tensió obliga el PIC a reiniciar-se, de manera que no podem operar tant el PIC com els servomotors al mateix carril de + 5V. Per tant, l’etiquetatge com a + 5V s’utilitza per alimentar el microcontrolador PIC, LCD i potenciòmetres i una sortida de regulador independent que s’etiqueta com a + 5V (2) s’utilitza per alimentar els servomotors.
Els cinc pins de sortida dels potenciòmetres que proporcionen una tensió variable de 0V a 5V estan connectats als pins analògics An0 a AN4 del PIC. Com que tenim previst utilitzar temporitzadors per generar PWM, els servomotors es poden connectar a qualsevol pin GPIO. He seleccionat pins de RD2 a RD6 per als servomotors, però pot ser qualsevol GPIO que trieu.
Com que el programa comporta molta depuració, una pantalla LCD de 16x2 també està connectada al portB del PIC. Es mostrarà el cicle de treball dels servomotors que s'estan controlant. A part d'això, també he ampliat les connexions per a tots els pins GPIO i analògics, per si de cas s'ha de connectar algun sensor en el futur. Finalment, també he connectat el pin del programador H1 per programar directament el PIC amb pickit3 mitjançant l'opció de programació ICSP.
Generació de senyals PWM al pin GPIO per al Servo Motor Control
Un cop el circuit estigui llest, hem d'esbrinar com generar senyals PWN al pin GPIO de PIC per controlar el servomotor. Ja hem cansat alguna cosa similar amb el mètode d'interrupció del temporitzador i hem tingut èxit. Aquí només anem a construir-lo a sobre, així que si sou nou aquí, us recomanaria que llegiu aquest tutorial anterior abans de continuar.
Tots els servomotors hobby funcionen amb una freqüència de 50Hz. És a dir, un cicle complet d’impulsos per a un servomotor serà 1/50 (F = 1 / T), que és de 20 ms. D’aquests 20 ms complets, el senyal de control només és de 0 a 2 ms, mentre que la resta del senyal sempre està apagat. La figura següent mostra com el temps d'encès només varia de 0 a 2 ms per girar el motor de 0 a 180 graus de la durada total de 20 ms.

Amb això en ment, hem d’escriure el programa de manera que el PIC llegeixi entre 0 i 1204 des del potenciòmetre i el mapegi a 0 i 100, que serà el cicle de treball del servomotor. Mitjançant aquest cicle de treball podem calcular el temps d’encesa del servomotor. A continuació, podem inicialitzar la interrupció del temporitzador per desbordar-se a un interval regular de manera que actuï de manera similar a la funció millis () a Arduino. Amb això, podem canviar el pin GPIO d’estat perquè sigui elevat durant la durada desitjada i desactivar-lo al cap de 20 ms (un cicle complet) i repetir el mateix procés. Ara, ja que hem entès la lògica, deixem-nos entrar al programa.
Programació PIC16F8771A per a Robotic Arm
Com sempre, es pot trobar el programa complet amb un vídeo al final d’aquesta pàgina, també es pot descarregar el codi amb tots els fitxers necessaris. En aquesta secció analitzarem la lògica del programa. El programa utilitza el mòdul ADC, el mòdul temporitzador i el mòdul LCD per controlar el braç robòtic. Si no esteu al corrent de com utilitzar les funcions ADC o temporitzadores ni per connectar una pantalla LCD amb PIC, podeu tornar als enllaços respectius per aprendre-les. L'explicació següent es dóna assumint que el lector està familiaritzat amb aquests conceptes.
Configuració del port del temporitzador 0
La secció més important del codi és configurar el temporitzador 0 per excedir-se de cada retard específic. Les fórmules per calcular aquest retard es poden donar com a
Retard = ((256-REG_val) * (Prescal * 4)) / Fosc
Mitjançant el registre OPTION_REG i TMR0, hem configurat el temporitzador 0 perquè funcioni amb un valor prescalar de 32 i el val REG estigui establert a 248. La freqüència de cristall (Fosc) que s’utilitza al nostre maquinari és de 20 MHz. Amb aquests valors es pot calcular el retard com a
Retard = ((256-248) * (32 * 4)) / (20000000) = 0,0000512 segons (o) = 0,05 msec
Per tant, ara hem configurat el temporitzador per desbordar-se cada 0,05 ms. A continuació es dóna el codi per fer el mateix
/ ***** Configuració del port per al temporitzador ****** / OPTION_REG = 0b00000100; // Temporitzador0 amb freq extern i 32 com a prescalar // També habilita PULL UP TMR0 = 248; // Carregueu el valor de temps de 0,0001 s; delayValue només pot estar entre 0-256 TMR0IE = 1; // Activa el bit d’interrupció del temporitzador al registre PIE1 GIE = 1; // Activa la interrupció global PEIE = 1; // Activa la interrupció perifèrica / *********** ______ *********** /
De la finestra de control total del servo motor de 0 ms a 2 ms podem controlar-lo amb una resolució de 0,05 ms, que ens permet tenir (2 / 0,05) 40 posicions diferents per al motor entre 0 i 180 graus. Podeu reduir encara més aquest valor si el vostre MCU el pot suportar per obtenir més posicions i un control precís.
Rutina de servei d’interrupció (ISR)
Ara que tenim el temporitzador 0 configurat per excedir-se de cada 0,05 ms, tindrem el senyal d'interrupció TMR0IF establert per a 0,05 ms. Així, dins de la funció ISR podem restablir aquest senyalador i incrementar una variable anomenada recompte per una. Per tant, ara aquesta variable augmentarà 1 per cada 0,05 ms.
void interrupt timer_isr () { if (TMR0IF == 1) // El marcador del temporitzador s'ha activat a causa del desbordament del temporitzador -> s'ha definit com a desbordament per cada 0,05 ms { TMR0 = 248; // Carregueu el valor del temporitzador TMR0IF = 0; // Esborra el compte de banderes d’interrupció del temporitzador ++; // Compteu els increments per 1 per cada 0,05 ms }
Càlcul del cicle de treball i puntualitat
A continuació, hem de calcular el cicle de treball i el temps per als cinc servomotors. Disposem de cinc servomotors, cadascun dels quals s’utilitza per controlar la secció individual del braç. Per tant, hem de llegir el valor ADC de tots cinc i calcular el cicle de treball i el temps de cadascun.
El valor ADC estarà entre 0 i 1024, que es pot convertir en un cicle de treball del 0% al 100% simplement multiplicant 0,0976 (100/1024 = 0,0976) al valor obtingut. Aquest cicle de treball del 0 al 100% s’ha de convertir a temps d’ACTIVACIÓ. Sabem que amb un cicle de treball del 100% el temps d’ACTIVACIÓ ha de ser de 2 ms (per 180 graus), de manera que multiplicar 0,02 (2/100 = 0,02) convertirà el cicle de treball de 0 a 100 a 0 a 2 ms. Però el nostre recompte de variables del temporitzador està configurat per augmentar una vegada per cada 0,05 ms. Això significa que el valor del recompte serà de 20 (1 / 0,05 = 20) per cada 1 ms. Per tant, hem de multiplicar 20 per 0,02 per calcular el temps exacte del nostre programa, que ens donarà el valor 0,4 (0,02 * 20 = 0,4). El codi del mateix es mostra a continuació, el podeu veure repetit 5 vegades per a tots els 5 pots utilitzant un bucle for. Els valors resultants s’emmagatzemen a la matriu T_ON.
for (int pot_num = 0; pot_num <= 3; pot_num ++) { int Pev_val = T_ON; POT_val = (ADC_Read (pot_num)); // Llegiu el valor de POT mitjançant ADC Duty_cycle = (POT_val * 0,0976); // Mapa de 0 a 1024 a 0 a 100 T_ON = Cicle_deure * 0,4; // 20 * 0,02
Seleccionar quin motor voleu girar
No podem controlar els cinc motors junts, ja que farà que el codi ISR alenteixi tot el microcontrolador. Per tant, hem de girar només un servomotor a la vegada. Per seleccionar quin servo voleu girar, el microcontrolador controla el temps d'encesa dels cinc servomotors i el compara amb el temps previ. Si hi ha un canvi en l’hora d’ACTIVACIÓ, podem concloure que el servo particular s’ha de moure. A continuació es mostra el codi del mateix.
if (T_ON! = Pev_val) { Lcd_Clear (); servo = pot_num; Lcd_Set_Cursor (2,11); Lcd_Print_String ("S:"); Lcd_Print_Char (servo + '0'); if (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 = (Cicle_deure / 10)% 10; Lcd_Print_Char (d1 + '0'); Lcd_Print_Char (d2 + '0');
També imprimim el cicle de servei a la pantalla LCD perquè l'usuari pugui conèixer la seva posició actual. Basant-se en el canvi de temps d’ACTIVACIÓ, el servo variable s’actualitza amb números del 0 al 4 cadascun representant motors individuals.
Control del servomotor a l’interior de l’ISR
Dins de l'ISR, el recompte de variables s'incrementa per cada 0,05 ms, això significa que per cada 1 ms la variable s'incrementarà en 20. Mitjançant això, hem de controlar els pins per produir senyal PWM. Si el valor del recompte és inferior al temps, el GPIO d'aquest motor s'encén mitjançant la línia següent
PORTD = PORTD - servo_code;
Aquí la matriu servo_code té el detall de pin dels cinc servomotors i, en funció del valor del servo variable, s'utilitzarà el codi d'aquest servomotor en particular. Aleshores és lògicament OR (-) amb els bits PORTD existents de manera que no molestem els valors d’un altre motor i actualitzem només aquest motor en particular. De la mateixa manera, per apagar el passador
PORTD = PORTD & ~ (servo_code);
Hem invertit el valor del bit mitjançant l’operador invers lògic (~) i després hem realitzat una operació AND (&) al PORTD per apagar només el pin desitjat deixant els altres pins en el seu estat anterior. A continuació es mostra el fragment de codi complet.
void interrupt timer_isr () { if (TMR0IF == 1) // El marcador del temporitzador s'ha activat a causa del desbordament del temporitzador -> configurat per desbordar cada 0,05 ms { TMR0 = 248; // Carregueu el temporitzador Valor TMR0IF = 0; // Esborra el compte de banderes d’interrupció del temporitzador ++; // Compteu increments per 1 per cada 0,05 ms -> el recompte serà de 20 per cada 1 ms (0,05 / 1 = 20)) } int servo_code = {0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100}; if (recompte> = 20 * 20) recompte = 0; if (count <= (T_ON)) PORTD = PORTD - servo_code; else PORTD = PORTD & ~ (servo_code); }
Sabem que el cicle total ha de durar 20 ms abans de tornar a engegar el pin GPIO. Per tant, comprovem si el recompte ha superat els 20 ms comparant el valor del recompte amb 400 (el mateix càlcul que es va esmentar anteriorment) i, si és així, hem d’inicialitzar el recompte per tornar a ser zero.
Simulació del codi de braç robòtic PIC
Sempre és millor simular el codi abans de portar-lo al maquinari real. Així que vaig fer servir Proteus per simular el meu codi i el vaig verificar perquè funcionés correctament. A continuació es mostra el circuit utilitzat per a la simulació. Hem utilitzat un oscil·loscopi per comprovar si es generen els senyals PWM segons es requereixi. També podem comprovar si els motors LCD i Servo giren com s’esperava.

Com podeu veure, la pantalla LCD mostra que el cicle de treball del motor D és 07 basat en el valor pot que és el tercer motor. De manera similar si es mou una altra olla, el cicle de treball d’aquesta olla i el seu número de motor es mostraran a la pantalla LCD. A continuació es mostra el senyal PWM que es mostra a l’oscil·loscopi.

El període de cicle total es mesura en 22,2 ms mitjançant l’opció de cursor de l’oscil·loscopi, que és molt a prop dels 20 ms desitjats. Finalment, estem segurs que el codi funciona, de manera que, per continuar amb el circuit, podem soldar-lo en una placa perf o utilitzar un PCB. No funcionarà fàcilment a la tauleta de suport perquè el POT sempre tendeix a donar alguns problemes a causa de les males connexions.
Disseny de PCB amb EasyEDA
Per dissenyar aquest braç robòtic PIC, hem escollit l'eina EDA en línia anomenada EasyEDA. Fa temps que l’utilitzo i el trobo molt convenient per la seva gran disponibilitat d’empremta i la seva naturalesa fàcil d’utilitzar. Després de dissenyar el PCB, podem demanar les mostres de PCB pels seus serveis de fabricació de PCB de baix cost. També ofereixen un servei d’aprovisionament de components on tenen un gran estoc de components electrònics i els usuaris poden demanar els components necessaris juntament amb la comanda de PCB.
Mentre dissenyeu els vostres circuits i PCBs, també podeu fer públics els vostres dissenys de circuits i PCBs perquè altres usuaris puguin copiar-los o editar-los i aprofitar-se del vostre treball, també hem fet públics tots els dissenys de circuits i PCB d’aquest circuit. l'enllaç següent:
easyeda.com/circuitdigest/pic-development-board-for-robotic-arm
Mitjançant aquest enllaç podeu demanar directament el mateix PCB que estem utilitzant en aquest projecte i utilitzar-lo. Un cop finalitzat el disseny, es pot veure el tauler com a model 3D, cosa que serà molt útil per visualitzar la forma en què apareix el tauler després de la fabricació. A continuació es mostra el model 3D del tauler que estem utilitzant. A part d'això, també podeu veure la capa superior i inferior del tauler per comprovar si la pantalla tàctil és com s'esperava.

Càlcul i ordenació de mostres en línia
Després de completar el disseny d’aquest PCB de robot PIC, podeu demanar el PCB a través de JLCPCB.com. Per demanar el PCB a JLCPCB, necessiteu Gerber File. Per descarregar fitxers Gerber del vostre PCB, feu clic al botó Generar fitxer de fabricació de la pàgina de l'editor EasyEDA i, a continuació, descarregueu el fitxer Gerber des d'allà o podeu fer clic a Comanda a JLCPCB com es mostra a la imatge següent. Això us redirigirà a JLCPCB.com, on podeu seleccionar el nombre de PCB que voleu demanar, quantes capes de coure necessiteu, el gruix del PCB, el pes del coure i fins i tot el color del PCB, com la instantània que es mostra a continuació:

Després d'haver seleccionat totes les opcions, feu clic a "Desa a la cistella" i se us dirigirà a la pàgina on podeu penjar el fitxer Gerber que hem descarregat d'EasyEDA. Pengeu el fitxer Gerber i feu clic a "Desa a la cistella". I, finalment, feu clic a Comanda de forma segura per completar la vostra comanda i, aleshores, obtindreu els vostres PCB pocs dies després. Estan fabricant el PCB a un preu molt baix, que és de 2 dòlars. El seu temps de construcció també és molt inferior, és a dir, 48 hores amb un lliurament DHL de 3-5 dies, bàsicament obtindreu els vostres PCB en una setmana després de la comanda.

Després de demanar el PCB, podeu comprovar el progrés de producció del PCB amb la data i l'hora. Per comprovar-ho, aneu a la pàgina del compte i feu clic a "Avanç de producció".

Després d’uns dies de demanar PCB, vaig obtenir les mostres de PCB en un bon embalatge, tal com es mostra a les imatges següents.


I després d’aconseguir aquestes peces, he soldat tots els components necessaris al PCB. També he soldat directament el POT directament en lloc d’utilitzar cables de connexió perquè els cables femella a femella que feia servir inicialment, donant tensions de sortida analògiques estranyes probablement a causa de contactes fluixos. Un cop muntats tots els components, el meu PCB semblava semblant.

És possible que us hàgiu adonat que només hi ha un 7805 en aquest tauler. Això es deu al fet que inicialment vaig pensar que podia sortir amb un regulador només per alimentar PIC i el servomotor i, més tard, em vaig adonar que en necessitava dos. Per tant, he utilitzat un circuit extern per alimentar els servomotors a través dels cables verds que veieu aquí.
No obstant això, no us heu de preocupar gaire perquè; Ara he fet els canvis al PCB. Podeu fer servir el PCB modificat i soldar els reguladors que hi ha a bord.
Funcionament del braç robòtic PIC
Després de tot el treball cansat, és hora de pagar. Soldeu tots els components de la placa i pengeu el programa al controlador PIC. A continuació es mostra el codi complet o es pot descarregar des d’aquí. El connector de programació que es proporciona a la placa us ajudarà a carregar el programa directament mitjançant Pickit 3 sense gaire molèsties. Un cop carregat el programa, hauríeu de veure la pantalla LCD que mostra el servo que s'està controlant actualment. Per obtenir més informació sobre la programació del microcontrolador PIC, seguiu el tutorial anterior.

Des d'allà, només podeu girar l'olla i comprovar com responen els servomotors a cada potenciòmetre. Un cop hàgiu entès el format, podeu controlar el braç robòtic per realitzar qualsevol acció que necessiteu per realitzar i divertir-vos. Podeu trobar el funcionament complet del projecte al vídeo enllaçat a continuació.
És a dir, els nois esperem que hàgiu entès el projecte i n’heu après alguna cosa nova. Si teniu alguna pregunta, deixeu-los a la secció de comentaris o utilitzeu els fòrums per a altres discussions tècniques.
