Brazo robotico ksr10 ps2x mayo 2015 a 9v version 3

Page 1

PROYECTO: AUTOMATIZACIÓN DEL BRAZO ROBÓTICO KSR10 Nombre del proyecto: "Robotic_Arm_KSR10_y_SD_y_PS2X.ino" (Realizado en Arduino 1.05.r2) Autor: Joaquín Berrocal Piris Fecha:

Mayo 2015

Autor : Joaquín Berrocal Piris Fecha: Mayo 2015

1


Al principio tengo una breve descripción y las fotos del proceso. Y al final, desde la página 36 a la 60, tengo escrito todo el programa realizado en Arduino 1.05.r2 Y de la 62 a 65 el tutorial uso de los drivers L298N “”Está ajustado para una tensión de alimentación a los drivers L298N de 9 V DC.””

Direcciones descarga documento”Version 1”: http://issuu.com/joaquinin/docs/proyecto_brazo_robotico_ksr10__ener http://www.slideshare.net/joaquinin1/proyecto-brazo-robotico-ksr10-enero-marzo-2015-46138135 /*proyecto "Robotic_Arm_KSR10_y_SD_PS2X " El código está más compacto y los motores con Autor: JOAQUÍN BERROCAL PIRIS mayor Torque. Fecha: Mayo 2015 (Es la versión 3 del proyecto inicial llamado "Robotic_Arm_KSR10_y_SD”, en el que no llevaba control por playstation)

Videos en youtube: http://youtu.be/b_8ESwbI6pk y versiones previas en https://youtu.be/FPJ2WEjW-uY en https://youtu.be/98JHhiSq_Go

y

/*proyecto "Robotic_Arm_KSR10_y_SD_y_PS2X" Este proyecto es muy similar al anterior que hice: "Robotic_Arm_KSR10_y_SD_V2.ino" solo que incorpora la opción de poder controlar los movimientos del brazo desde un mando de la playstation ps2x. Me sirvo de la librería "#include <PS2X_lib.h> " adaptándola a mi mando ps2x comprado en china que no es original al de SONY aunque sí compatible; precio 14,92$. --------------------------------------------------------En mi ps2x chino debo hacer el ps2x.config_gamepad(…) doblemente para que sea reconocido el módulo receptor ps2x lo que descubrí después de muchas pruebas en las que el módulo receptor no era siempre reconocido. Además también pongo el pin "acknoledge" a masa. si lo dejo al aire se dificulta el reconocimiento del módulo. En el "Setup ()" poner dos veces ; //1ª ) setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error error = ps2x.config_gamepad (14,15,16,17,true,true); delay(50); aquí puedo bajar incluso suprimir este delay(50) //2ª) setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error error = ps2x.config_gamepad(14,15,16,17, true, true); delay(50); // este es necesario aunque sí acepta menos tiempo. --------------------------------------------------------Autor: JOAQUÍN BERROCAL PIRIS Fecha: Mayo 2015 BREVE EXPLICACIÓN: El proyecto está realizado sobre una ARDUINO MEGA 2560 por necesitar más pines que los de la UNO 3. Consite en controlar de forma automática, mediante joystick, el movimiento de un brazo robótico de la marca KSR10 de Velleman con 5 motorcitos de 6 voltios, acepta incluso hasta 12V. +Dispone de un interruptor para permitir grabar los movimientos que realice y serán grabados sobre tarjeta SD. ""El momento de permitir la grabación será indicado con led verde. +Dispone también de un interruptor para permitir secuenciar los movimientos grabados de forma continua mientras se mantenga activado. será indicado mediante led Azul. +Dispone también de un interruptor para hacer lectura desde el mando de la PS2X (cuando está en (+) el pin 12 de arduino 2


o bien desde los Josystick del tablero cuando el pin 12 está a masa (-) "TODOS ESTOS INTERRUPTORES con su palanca HACIA ABAJO están a nivel ALTO" + Cuando se activa el programa, lo primero que hará será ir a posición HOME. que corresponde a posición de 89º a 91º en los potenciómetros de los respectivos motores. + También cada vez q pulse cualquiera de los dos interruptores lo primero será llevar el brazo a posición HOME. por consiguiente hasta que no esté en esa posición no se permitirá grabar ni secuenciar los movimientos. Esperar a que se encienda el led verde para permitir grabar los movimientos o el led Azul para q se secuencien los movimientos grabados en la SD. + El proyecto está comunicado por el USB pines 0-1 para comunicar a través de puerto serial mensajes varios entre ellos datos de posición. la tengo como ayuda para ajustar el proyecto. FINALMENTE EL PROYECTO HA QUEDADO BASTANTE AJUSTADO Y CALIBRADO con sus pequeñas desviaciones debido a las holguras de engranajes/potenciómetros e histéresis dadas para precisión y calibración. El desajuste aproximado es de unos +- 1º. **No uso ninguna librería específica para la calibración de la posición de los motores+ **aunque hay una librería llamada "PID_v1.h" para el control de movimientos pero no hago uso por no tener datos suficientes para su manejo.** MATERIALES Y CONEXIONES: -. Brazo robótico 50€ marca KSR10 de velleman -. Le he colocado 5 potenciómetros 10K para control de posiciones -. 5 Motores de 6 voltios DC -. 3 Joystick para control movimiento de los 5 motores -. 5 Potenciómetros control posición ****CONEXIÓN ANALOGICA DE LOS Joystick y Potenc****** Joystick ---- Potenciometro motor 1 ---- A0 --------- A5 motor 2 ---- A1 --------- A6 motor 3 ---- A2 --------- A7 motor 4 ---- A3 --------- A8 motor 5 ---- A4 --------- A9 ***************************************************** -. 3 Amplificadores de potencia L298N que utilizo para alimentar y cambiar direción de giro de los motores, admiten hasta 2 Amp con puntas de hasta 4A. por canal (realmente estos 5 motores, en conjunto, no llegan a a sobrepasar 1 A. como mucho 1,5 A. -. tarjeta SD para grabación de las secuencia de movimientos que deseo memorizar microSD Card Adapter . Pin CS de la Tarjeta al pin 53 de la Arduino Mega 2560 Si utilizase la arduino Uno sería al pin 10 y en la ethernet el 4 conexión pines Tarjeta SD; Ardu Mega Ard UNO CS --------- 53 ------- 10 "en la ethernet shield el 4" clk/sck --- 52 ------- 13 MOSI ----- 51 ------- 11 MISO ------- 50 ------ 12 3


-. Conexión de los Drivers amplificadores a la arduino Mega: Los Pines PWM de arduino a la conexion ENA o ENB del L298N los otros dos numero son las entradas in1 in2 del amplificador conectadas a los pines de arduino nº 22 y 23 ... pin PWM IN1 / IN2 Motor 1-----2 --- 22 / 23 Motor 2-----3 --- 24 / 25 Motor 3-----4 --- 26 / 27 Motor 4-----5 --- 28 / 29 Motor 5-----6 --- 30 / 31 -. Conexión del receptor PS2X playStation a la placa arduino mega: SE DEBE EFECTUAR A TRAVÉS DE UN CONVERSOR de señal de 5v a 3,3V. Pues LA PLACA ARDUINO TRABAJA A 5V y la playstation trabaja a 3 Voltios. IMPORTANTE. conectar a dicha placa los 3,3V. en su lado de nivel bajo y de ahí al módulo recptor PS2X. y en el lado de alta, alimentarlo a 5V. por lo menos en mi conversor, pues realmente no convierte de los 5 a 3,3V en la alimentación lo tengo comprobado. setup pins and settings: ps2x.config_GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error error = ps2x.config_gamepad(14,15,16,17, true, true); //son los pines que utilizo de la arduino MEGA pin Receptor PS2X pin Arduino 7 ---- CLK (clok) ---------------- 14 2 ---- CMD (comand) --------- 15 6 ---- ATT (attention) --------- 16 [EL ATT también se llama CS (Chip Select)] 1 ---- DAT (data) --------------- 17 5 ---- VCC 3,3V ---------------- pin de 3,3V --> conectarlo al conversor de señal y al receptor PS2X 4 ---- GND masa -------------- GND 9 ---- Acknolage ------------- a GND IMPORTANTE si lo dejo al aire problemas reconocimiento del módulo "N/C no conexinados los pines 3 y 8 del módulo recepetor." *************MANDO PLAYSTATION PS2X. OBSERVACIONES:************************************ -. En la lectura analógica de los joystick del mando de la playStation se leen Tope hacia adelante; valor 0. Tope hacia atrás 255 ("y NO 1023") Tope a la Izqda ; valor 0 . Topa hacia la Dcha 255 ("y NO 1023") Ejemplo de lectura analógica: donde se muestra que la lectura va de 0 a 255 y la convierto en 180 a 0 servoVal = map(ps2x.Analog(valorPSS),0,255,180,0); //Aquí se lee el valor analógico del mando ps2x **************************************************************************************** ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ El mando PS22X tiene 13 pulsadores y dos JOYSTICK con 2 pulsadores mas y cada uno tiene un nombre descriptivo y su valor decimal. Indicaré el valor decimal de aquellos que he utilizado en este proyecto para manejo de los motores. Nombre (valor decimal) PSB_L1 PSB_PAD_UP PSB_L2 PSB_PAD_DOWN PSB_R1 PSB_PAD_LEFT >>>>(11) y como valor analógico: PSAB_PAD_LEFT >>>>(9) PSB_R2 PSB_PAD_RIGHT >>>(12) y como valor analógico: PSAB_PAD_RIGHT >>>(10) PSB_SELECT PSB_START PSB_MODE PSB_BLUE y como valor analógico: PSAB_BLUE PSB_PINK y como valor analógico: PSAB_PINK 4


PSB_RED y como valor analógico: PSAB_RED PSB_GREEN y como valor analógico: PSAB_GREEN Joysticks; PSS_LY (8) utilizado en el proyecto PSS_LX (7) PSS_RY (6) utilizado en el proyecto PSS_RX (5) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -.(*los leds son de cátodo común (-)) -. ledRojo al pin 9 aviso que se dirige al Home (sucede al activar cualquier interruptor) -. ledVerde al pin 10 se pueden grabar los movimientos. (interruptor grabar LOW) -. ledAzul al pin 11 secuenciar movimientos grabados (interruptor secuenciar LOW) -. led amarillo intenso (R 240 V 245 A 7) mediante: analogWrite (pinPWM, valor de 0 a 255) analogWrite (9,240); analogWrite (10,240) ; analogWrite (11,240); -. El LED de iluminación del Brazo robótico, conectado al pin 18 de arduino -. interruptor para grabar movimientos: al pin 7 -. interruptor para secuenciar movimientos grabados al pin 8 -. interruptor PARA seleccionar los Joystick o bien la PS2X al pin 12 (la resistencia de TODOS los interruptores puestas a + Pull-up al activar el pulsador conecto el pin 7 o el 8 o el 12 a masa (-)) -.Niveles de giro máximo : Tan solo tengo limites max permitidos por software al motor 1 que es la pinza y al motor 5 encargado del giro transversal del brazo. el M 2-3-4 No les tengo límites. Motor 1 de 114 patillas cerradas a 57º plenamente abiertas Motor 2 de 50º a 126º Motor 3 de 97º a 64º Motor 4 de 42º a 135º Motor 5 de 120º a 70º (Realmente acepta 127º a 63º pero para evitar las inercias y que choque con palanca potenciómetro 5) **** OTROS DATOS Interesante en la configuración del programa: ****** -. Posición HOME: valores potenciométros entre 89º a 91º . Es decir un +/- 1º respecto a 90º para permitir una cierta histéresis que impida estén fluctuando el accionamiento de los motores para mantenr la posición. +Cuando se va acercando a 90º reduzco la velocidad entorno a 50 / 110 para mejor ajuste. -. Posición JOYSTICK posición neutra de los joystick para evitar accionamientos indeseados neutra de 80 a 94. todo en LOW / LOW / LOW (el enable y int 1 int 2 del amplificador L298N) - Si el valor leído del joystic < 80 giro en un sentido: LOW / HIGH - si el valor leído del joystic > 94 giro en sentido contrario: HIGH / LOW En la función; Joystick ( int pinanalogico, int pinPWM, int int1, int int2, char letra) tengo el accionamiento manual de los motores más chequeo interruptores de grabar o secuenciar desde esta función evito sobrepasar los grados de giro para el motor 1 de la pinza y del motor 5 del giro transversal del brazo. -.en HOME valor global de accionamiento 180. Motor 1 a 60 motor 2 a 150. Y cuando se acerca a posición home 90º; if (servoVal >= 83) and (servoVal < 89) and (motor == "motor 1") y en if ((servoVal >= 92)and(servoVal <= 95) and (motor == "motor 1")) 5


velocidad mas lenta motor 1 a 40 y para Motor 2 a 100 para el resto de motores 110 -.En Joystic valor global de accionamiento 180, motor 1 a 80, motor 2 a 150 -.En ActivarMotores valor global de accionamiento 200, motor 1 a 90, motor 2 a 170 motor 5 200 lo puedo suprimir*** Para trabajar con LA LCD 4X16 utilizando 2 hilos el de reloj SCL y el de Datos utilizar SDA --- 20 SCL -- 21 ("En este proyecto no la utilizo") */

6


F O T O S PROCESO CONSTRUCCIÓN Modelo KSR10 DE vELLEMAN

7


MONTAJE COMPONENTES, Complicadillo

รง

8


9


10


11


12


13


14


15


PRIMERAS PRUEBAS

16


¿CÓMO COLOCAR LOS POTENCIÓMETROS DE POSCIÓN MOTORES? 1er intento

17


¡¡¡¡Segundo intento de colocación potenciómetros, algo más elaborada y más exitosa!!!

18


19


20


21


Se continúa haciendo pruebas…. Tablero de control con un sólo Joystick y dos potenciómetros, dos drivers L298N ..

22


23


Utilizo la placa ETHERNET por tener lector de micro tarjetas SD donde mi intención será grabar los movimientos que desee utilizando los Joystick ara luego secuenciarlos de forma repetitiva y automática. (Más adelante cuando me llegue la placa micro SD dejaré de utilizar la ETHERNET.)

24


COLOCACIÓN DE LOS NUEVOS POTENCIÓMETROS CON LOS QUE FINALMENTE SE QUEDARÁ EL PROYECTO. (tardaron mucho de china, lo que supuso un problema para poder avanzar.)

25


26


ESTO YA ES OTRA COSA. MÁS ESTABLES Y FIELES LOS VALORES LEÍDOS

27


28


POR ÚLTIMO ME DECIDO A CONTROLAR TAMBIÉN EL MOVIMIENTO GIRATORIO CON EL MOTOR 5 (Gran complicación debido a no tener muy claro dónde y cómo fijarlo con su palanca de accionamiento)

29


30


Nueva mesa controladora. Dispone de un interruptor más para seleccionar que sea controlado desde los Joysticks de la mesa; posición “Joystick” o bien desde el mando de la PlayStation “PS2X”

31


Mรณdulo receptor de la PlayStation y el conversor de 5 a 3 voltios para la comunicaciรณn de la placa arduino con el mรณdulo receptor

32


Mando y receptor de la playStation PS2X

CONVERSOR DE 5 V A 3 V. Por otro lado, en la mayoría de los casos necesitaremos un conversor lógico de nivel de 3,3V a 5V. El motivo es que, por lo general, nuestro Arduino opera a 5V, mientras que la electrónica del mando de la PS2 funciona a 3,3V. Podríamos hacer nuestro propio circuito de adaptación, pero no tienen ningún sentido dado que se venden por 1,10€, gastos de envío incluidos.

Para encontrar el conversor simplemente buscar “level converter” en Ebay. Estamos buscando un artículo similar al siguiente “JY MCY I2C LEVEL CONVERTER”, un dispositivo que permite adaptar 4 señales de forma bidireccional. Fijaros que el modelo que queremos tiene 6 pines (no compréis uno de 4 pines, que solo pueden adaptar 2 señales). El Acknolage CONECTARLO A MASA para que se reconozca fácilmente el módulo receptor inalámbrico

33


A continuación usamos una protoboard para realizar las conexiones con nuestro conversor digital (o lo soldamos directamente). En el lado de baja tensión se conectan las cuatro señales del mando, ground, y alimentación, que será proporcionada por Arduino. En el lado de alta tensión conectamos cuatro pines, ground, y +5V que será convertido por el conversor a +3,3V para alimentar el receptor. El esquema definitivo es el siguiente. Acknolage a masa Y el terminal de 3 V del convertidor unirlo también con los 3,3V de la placa arduino, al menos en mi convertidor comprado que no es exactamente igual a ést

34


Esquema de la PlayStation con el nombre que reciben sus pulsadores y Joystick (Este no es inalรกmbrico como el que tengo instalado pero me vale su descripciรณn)

35


Al principio tengo una breve descripción y las fotos del proceso. Y al final, desde la página 36 a la 60, tengo escrito todo el programa realizado en Arduino 1.05.r2 Y de la 62 a 65 el tutorial uso de los drivers L298N “”Está ajustado para una tensión de alimentación a los drivers L298N de 9 V DC.””

Direcciones descarga documento”Version 1”: http://issuu.com/joaquinin/docs/proyecto_brazo_robotico_ksr10__ener http://www.slideshare.net/joaquinin1/proyecto-brazo-robotico-ksr10-enero-marzo-2015-46138135 /*proyecto "Robotic_Arm_KSR10_y_SD_PS2X " El código está más compacto y los motores con Autor: JOAQUÍN BERROCAL PIRIS mayor Torque. Fecha: Mayo 2015 (Es la versión 3 del proyecto inicial llamado "Robotic_Arm_KSR10_y_SD”, en el que no llevaba control por playstation)

Videos en youtube: http://youtu.be/b_8ESwbI6pk y versiones previas en https://youtu.be/FPJ2WEjW-uY en https://youtu.be/98JHhiSq_Go

y

/*proyecto "Robotic_Arm_KSR10_y_SD_y_PS2X" Este proyecto es muy similar al anterior que hice: "Robotic_Arm_KSR10_y_SD_V2.ino" solo que incorpora la opción de poder controlar los movimientos del brazo desde un mando de la playstation ps2x. Me sirvo de la librería "#include <PS2X_lib.h> " adaptándola a mi mando ps2x comprado en china que no es original al de SONY aunque sí compatible; precio 14,92$. --------------------------------------------------------En mi ps2x chino debo hacer el ps2x.config_gamepad(…) doblemente para que sea reconocido el módulo receptor ps2x lo que descubrí después de muchas pruebas en las que el módulo receptor no era siempre reconocido. Además también pongo el pin "acknoledge" a masa. si lo dejo al aire se dificulta el reconocimiento del módulo. En el "Setup ()" poner dos veces ; //1ª ) setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error error = ps2x.config_gamepad (14,15,16,17,true,true); delay(50); aquí puedo bajar incluso suprimir este delay(50) //2ª) setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error error = ps2x.config_gamepad(14,15,16,17, true, true); delay(50); // este es necesario aunque sí acepta menos tiempo. --------------------------------------------------------Autor: JOAQUÍN BERROCAL PIRIS Fecha: Mayo 2015 BREVE EXPLICACIÓN: El proyecto está realizado sobre una ARDUINO MEGA 2560 por necesitar más pines que los de la UNO 3. Consite en controlar de forma automática, mediante joystick, el movimiento de un brazo robótico de la marca KSR10 de Velleman con 5 motorcitos de 6 voltios, acepta incluso hasta 12V. +Dispone de un interruptor para permitir grabar los movimientos que realice y serán grabados sobre tarjeta SD. ""El momento de permitir la grabación será indicado con led verde. 36


+Dispone también de un interruptor para permitir secuenciar los movimientos grabados de forma continua mientras se mantenga activado. será indicado mediante led Azul. +Dispone también de un interruptor para hacer lectura desde el mando de la PS2X (cuando está en (+) el pin 12 de arduino o bien desde los Josystick del tablero cuando el pin 12 está a masa (-) "TODOS ESTOS INTERRUPTORES con su palanca HACIA ABAJO están a nivel ALTO" + Cuando se activa el programa, lo primero que hará será ir a posición HOME. que corresponde a posición de 89º a 91º en los potenciómetros de los respectivos motores. + También cada vez q pulse cualquiera de los dos interruptores lo primero será llevar el brazo a posición HOME. por consiguiente hasta que no esté en esa posición no se permitirá grabar ni secuenciar los movimientos. Esperar a que se encienda el led verde para permitir grabar los movimientos o el led Azul para q se secuencien los movimientos grabados en la SD. + El proyecto está comunicado por el USB pines 0-1 para comunicar a través de puerto serial mensajes varios entre ellos datos de posición. la tengo como ayuda para ajustar el proyecto. FINALMENTE EL PROYECTO HA QUEDADO BASTANTE AJUSTADO Y CALIBRADO con sus pequeñas desviaciones debido a las holguras de engranajes/potenciómetros e histéresis dadas para precisión y calibración. El desajuste aproximado es de unos +- 1º. **No uso ninguna librería específica para la calibración de la posición de los motores+ **aunque hay una librería llamada "PID_v1.h" para el control de movimientos pero no hago uso por no tener datos suficientes para su manejo.** MATERIALES Y CONEXIONES: -. Brazo robótico 50€ marca KSR10 de velleman -. Le he colocado 5 potenciómetros 10K para control de posiciones -. 5 Motores de 6 voltios DC -. 3 Joystick para control movimiento de los 5 motores -. 5 Potenciómetros control posición ****CONEXIÓN ANALOGICA DE LOS Joystick y Potenc****** Joystick ---- Potenciometro motor 1 ---- A0 --------- A5 motor 2 ---- A1 --------- A6 motor 3 ---- A2 --------- A7 motor 4 ---- A3 --------- A8 motor 5 ---- A4 --------- A9 ***************************************************** -. 3 Amplificadores de potencia L298N que utilizo para alimentar y cambiar direción de giro de los motores, admiten hasta 2 Amp con puntas de hasta 4A. por canal (realmente estos 5 motores, en conjunto, no llegan a a sobrepasar 1 A. como mucho 1,5 A. -. tarjeta SD para grabación de las secuencia de movimientos que deseo memorizar microSD Card Adapter . Pin CS de la Tarjeta al pin 53 de la Arduino Mega 2560 Si utilizase la arduino Uno sería al pin 10 y en la ethernet el 4 37


conexión pines Tarjeta SD; Ardu Mega Ard UNO CS --------- 53 ------- 10 "en la ethernet shield el 4" clk/sck --- 52 ------- 13 MOSI ----- 51 ------- 11 MISO ----- 50 ------- 12 -. Conexión de los Drivers amplificadores a la arduino Mega: Los Pines PWM de arduino a la conexion ENA o ENB del L298N los otros dos numero son las entradas in1 in2 del amplificador conectadas a los pines de arduino nº 22 y 23 ... pin PWM IN1 / IN2 Motor 1-----2 --- 22 / 23 Motor 2-----3 --- 24 / 25 Motor 3-----4 --- 26 / 27 Motor 4-----5 --- 28 / 29 Motor 5-----6 --- 30 / 31 -. Conexión del receptor PS2X playStation a la placa arduino mega: SE DEBE EFECTUAR A TRAVÉS DE UN CONVERSOR de señal de 5v a 3,3V. Pues LA PLACA ARDUINO TRABAJA A 5V y la playstation trabaja a 3 Voltios. IMPORTANTE. conectar a dicha placa los 3,3V. en su lado de nivel bajo y de ahí al módulo recptor PS2X. y en el lado de alta, alimentarlo a 5V. por lo menos en mi conversor, pues realmente no convierte de los 5 a 3,3V en la alimentación lo tengo comprobado. setup pins and settings: ps2x.config_GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error error = ps2x.config_gamepad(14,15,16,17, true, true); //son los pines que utilizo de la arduino MEGA pin Recptor PS2X pin Arduino 7 CLK (clok) ---------------- 14 2 CMD (comand) --------- 15 6 ATT (attention) --------- 16 [EL ATT también se llama CS (Chip Select)] 1 DAT (data) --------------- 17 5 VCC 3,3V ---------------- pin de 3,3V --> conectarlo al conversor de señal y y al receptor PS2X 4 GND masa -------------- GND 9 Acknolage ------------- a GND IMPORTANTE si lo dejo al aire problemas reconocimiento del módulo "N/C no conexinados los pines 3 y 8 del módulo recepetor." *************MANDO PLAYSTATION PS2X. OBSERVACIONES:************************************ -. En la lectura analógica de los joystick del mando de la playStation se leen Tope hacia adelante; valor 0. Tope hacia atrás 255 ("y NO 1023") Tope a la Izqda ; valor 0 . Topa hacia la Dcha 255 ("y NO 1023") Ejemplo de lectura analógica: donde se muestra que la lectura va de 0 a 255 y la convierto en 180 a 0 servoVal = map(ps2x.Analog(valorPSS),0,255,180,0); //Aquí se lee el valor analógico del mando ps2x **************************************************************************************** ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ El mando PS22X tiene 13 pulsadores y dos JOYSTICK con 2 pulsadores mas y cada uno tiene un nombre descriptivo y su valor decimal. Indicaré el valor decimal de aquellos que he utilizado en este proyecto para manejo de los motores. Nombre (valor decimal) PSB_L1 PSB_PAD_UP PSB_L2 PSB_PAD_DOWN 38


PSB_R1 PSB_PAD_LEFT >>>>(11) y como valor analógico: PSAB_PAD_LEFT >>>>(9) PSB_R2 PSB_PAD_RIGHT >>>(12) y como valor analógico: PSAB_PAD_RIGHT >>>(10) PSB_SELECT PSB_START PSB_MODE PSB_BLUE y como valor analógico: PSAB_BLUE PSB_PINK y como valor analógico: PSAB_PINK PSB_RED y como valor analógico: PSAB_RED PSB_GREEN y como valor analógico: PSAB_GREEN Joysticks; PSS_LY (8) utilizado en el proyecto PSS_LX (7) PSS_RY (6) utilizado en el proyecto PSS_RX (5) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -.(*los leds son de cátodo común (-)) -. ledRojo al pin 9 aviso que se dirige al Home (sucede al activar cualquier interruptor) -. ledVerde al pin 10 se pueden grabar los movimientos. (interruptor grabar LOW) -. ledAzul al pin 11 secuenciar movimientos grabados (interruptor secuenciar LOW) -. led amarillo intenso (R 240 V 245 A 7) mediante: analogWrite (pinPWM, valor de 0 a 255) analogWrite (9,240); analogWrite (10,240) ; analogWrite (11,240); -. El LED de iluminación del Brazo robótico, conectado al pin 18 de arduino -. interruptor para grabar movimientos: al pin 7 -. interruptor para secuenciar movimientos grabados al pin 8 -. interruptor PARA seleccionar los Joystick o bien la PS2X al pin 12 (la resistencia de TODOS los interruptores puestas a + Pull-up al activar el pulsador conecto el pin 7 o el 8 o el 12 a masa (-)) -.Niveles de giro máximo : Tan solo tengo limites max permitidos por software al motor 1 que es la pinza y al motor 5 encargado del giro transversal del brazo. el M 2-3-4 No les tengo límites. Motor 1 de 114 patillas cerradas a 57º plenamente abiertas Motor 2 de 50º a 126º Motor 3 de 97º a 64º Motor 4 de 42º a 135º Motor 5 de 120º a 70º (Realmente acepta 127º a 63º pero para evitar las inercias y que choque con palanca potenciómetro 5) **** OTROS DATOS Interesante en la configuración del programa: ****** -. Posición HOME: valores potenciométros entre 89º a 91º . Es decir un +/- 1º respecto a 90º para permitir una cierta histéresis que impida estén fluctuando el accionamiento de los motores para mantenr la posición. +Cuando se va acercando a 90º reduzco la velocidad entorno a 50 / 110 para mejor ajuste. -. Posición JOYSTICK posición neutra de los joystick para evitar accionamientos indeseados neutra de 80 a 94. todo en LOW / LOW / LOW (el enable y int 1 int 2 del amplificador L298N) - Si el valor leído del joystic < 80 giro en un sentido: LOW / HIGH - si el valor leído del joystic > 94 giro en sentido contrario: HIGH / LOW En la función; Joystick ( int pinanalogico, int pinPWM, int int1, int int2, char letra) tengo el accionamiento manual de los motores más chequeo interruptores de grabar o secuenciar 39


desde esta función evito sobrepasar los grados de giro para el motor 1 de la pinza y del motor 5 del giro transversal del brazo. -.en HOME valor global de accionamiento 180. Motor 1 a 60 motor 2 a 150. Y cuando se acerca a posición home 90º; if (servoVal >= 83) and (servoVal < 89) and (motor == "motor 1") y en if ((servoVal >= 92)and(servoVal <= 95) and (motor == "motor 1")) velocidad mas lenta motor 1 a 40 y para Motor 2 a 100 para el resto de motores 110 -.En Joystic valor global de accionamiento 180, motor 1 a 80, motor 2 a 150 -.En ActivarMotores valor global de accionamiento 200, motor 1 a 90, motor 2 a 170 motor 5 200 lo puedo suprimir*** Para trabajar con LA LCD 4X16 utilizando 2 hilos el de reloj SCL y el de Datos utilizar SDA --- 20 SCL -- 21 ("En este proyecto no la utilizo") */

#include <SD.h> File miarchivo; // -----CONFIGURACIÓN DE PINES y VARIABLES GLOBALES---const int CS_SD = 53;//53 habitual de las MEGA. en Arduino UNO sería el 10 //sin embargo lo llamo en el proyecto por el número 53 int servoVal,valorPotX,pinAnalog; // variables a leer por los puertos analógicos int valorAnterior; byte Interruptor_grabar = 7; //el pin 7 para grabar si está a masa byte Interruptor_secuenciar = 8; //el pin 8 a nivel 0 para secuenciar el movimiento grabado byte Interruptor_PS2X_Joystick = 12;//nivel 1 manejo con los Joystick de la mesa // nivel 0 manejo con el mando de la playStation PS2X

int verde = 10; //pin 10 Se puede Grabar int rojo = 9; //pin 9 mientras se va al home al pulsar interruptores de Grabar o Secuenciar. int azul = 11; //pin 11 para secuenciar_movimientos //------PINES CONTROL L298N puente en H 2 Amp por canal //motor 1 motor de pinzas const int ENA_1 = 2; //pin 2 pulsos PWM control de velocidad const int IN1_1 = 22;//pin 22-23 nivel 1 o 0 para cambiar sentido giro const int IN2_1 = 23; // motor 2 const int ENA_2 = 3;//pin 3 pulsos PWM control de velocidad const int IN1_2 = 24;//pin 24-25 nivel 1 o 0 para cambiar sentido giro const int IN2_2 = 25; // motor 3 const int ENA_3 = 4;//pin 4 pulsos PWM control de velocidad 40


const int IN1_3 = 26;//pin 26-27 nivel 1 o 0 para cambiar sentido giro const int IN2_3 = 27; // motor 4 const int ENA_4 = 5;//pin 5 pulsos PWM control de velocidad const int IN1_4 = 28;//pin 28-29 nivol 1 o 0 para cambiar sentido giro const int IN2_4 = 29; // motor 5 const int ENA_5 = 6; //pin 6 pulsos PWM control de velocidad const int IN1_5 = 30;//pin 30-31 nivel 1 o 0 para cambiar sentido giro const int IN2_5 = 31; byte FlagGrabar = 0; byte FlagSecuenciar = 0; int i = 0; //variable global int valorInt ; //para convertir los valores de los grados a enteros y activar el motor char c ; String valorString = ""; // ------- para el mando PS2 --------#include <PS2X_lib.h> //for v1.6 PS2X ps2x; // create PS2 Controller Class //right now, the library does NOT support hot pluggable controllers, meaning //you must always either restart your Arduino after you conect the controller, //or call config_gamepad(pins) again after connecting the controller. int error = 0; byte type = 0; byte vibrate = 0; int le = 0; int led = 18; //Para activar el led de iluminaciรณn del brazo robรณtico. Se activa //desde la PS2X al pulsar la tecla azul (X) y se desconecta al pulsar la tecla roja (O) //-----------------------------------//+++++CONJUNTO DE RUTINAS EMPLEADAS+++++++ //+++++++++++++++++++++++++++++++++++++++++ void ledRojo() //activa led rojo { digitalWrite(rojo,HIGH); //se enciende avisi movimiento a HOME digitalWrite(verde,LOW); //se enciende permite grabar movimientos digitalWrite(azul,LOW); //se enciende para indicar secuencia de movimientos } void ledVerde() //activa led Verde { digitalWrite(rojo,LOW); digitalWrite(verde,HIGH); digitalWrite(azul,LOW); } void ledAzul() //activa led Azul { digitalWrite(rojo,LOW); digitalWrite(verde,LOW); 41


digitalWrite(azul,HIGH); } void apagarLeds() //activa led Azul { digitalWrite(rojo,LOW); digitalWrite(verde,LOW); digitalWrite(azul,LOW); }

//// ++++++FUNCIÓN PARA EL CONTROL CON EL MANDO DE LA PS2X +++++++++++ // ----FUNCION JOYSTICK para manejo manual motores ---------int JoystickPS2X (int valorPSS, int pinAnalogico,int pinPWM,int int1,int int2,char letra) { //+++ los valores para control desde el mando de la PS2X ++++ if (digitalRead(Interruptor_PS2X_Joystick)== HIGH) { if (ps2x.Button(PSB_BLUE)) { digitalWrite(led,HIGH); } if (ps2x.Button(PSB_RED)) { digitalWrite(led,LOW); } //-----------------------------------------------------------------------------------//CON ESTAS INSTRUCCIONES invirtiendo 180,0 /0,180 / o 90,0 / 0,90 //CONSIGO ASIGNAR LOS MISMOS SENTIDOS DE GIRO CON LOS JOYSCTICK DEL MANDO PS2X que con los de la MESA CONTROLADORA // En los joystick del mando PS2X el //tope hacia el frente valor 0 //tope hacia atrás valor 255 ("No valor 1023") // si no he pulsado los pulsadores PSB_PAD_RIGHT (9)- PSB_PAD_LEFT (10) //que utilizaré para el control del motor 5 // ni tampoco el joystick PSS_LY (8) control Motor 1 ni el PSS_RY (6) control Motor 3 if ((valorPSS != 9) and (valorPSS != 10)and (valorPSS != 8)and (valorPSS != 6)) { servoVal = map(ps2x.Analog(valorPSS),0,255,180,0); //Aquí se lee el valor analógico del mando ps2x 180,0 delayMicroseconds(100); // tiempo para la conversion Analogica/digital son 100usg que son 0,1 ms. //MODIFICAR LOS MARGENES SI FUERA NECESARIO } //fin del if ((valorPSS) != 9) and (valorPSS) != 10)and (valorPSS != 8)and (valorPSS != 6)) else if ((valorPSS == 8)or (valorPSS == 6)) // Para el Motor 1 y Motor 3 De esta manera consigo girar los motores // en el mismo sentido que con los joystick de la mesa controladora 42


{

//Aquí se lee el valor analógico del mando ps2x 0,180 //invertido para tener el mismo giro que con los joystick de la mesa

servoVal = map(ps2x.Analog(valorPSS),0,255,0,180); delayMicroseconds(100); // tiempo para la conversion Analogica/digital son 100usg que son 0,1 ms. //MODIFICAR LOS MARGENES SI FUERA NECESARIO } //-------------------------------------------------------------------------------------------else if (valorPSS == 9) // Para giro a DCHA del Motor 5 { servoVal = map(ps2x.Analog(valorPSS),0,255,90,180); //Aquí se lee el valor analógico del mando ps2x 90,180 delayMicroseconds(100); // tiempo para la conversion Analogica/digital son 100usg que son 0,1 ms. //MODIFICAR LOS MARGENES SI FUERA NECESARIO } else if (valorPSS == 10) // Para giro a IZQDA del Motor 5 { servoVal = map(ps2x.Analog(valorPSS),0,255,90,0); //Aquí se lee el valor analógico del mando ps2x 90,0 delayMicroseconds(100); // tiempo para la conversion Analogica/digital son 100usg que son 0,1 ms. //MODIFICAR LOS MARGENES SI FUERA NECESARIO } } // fin del if (digitalRead(Interruptor_PS2X_Joystick)== HIGH) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++ Si el interruptor está a nivel LOW +++++++++++ //+++control desde los Joystick de la mesa controladora ++ if (digitalRead(Interruptor_PS2X_Joystick)== LOW) { servoVal = analogRead(pinAnalogico); servoVal = map (servoVal,0,1023,0,180); delayMicroseconds(100); // tiempo para la conversion Analogica/digital son 100usg que son 0,1 ms. //MODIFICAR LOS MARGENES SI FUERA NECESARIO

} //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ------- AQUÍ IRÍAN LAS INSTRUCCIONES donde comprobé ----------//el fallo en la lectura de los interruptores por mala colocación //de los parentesis // ""la tengo guardada al final del programa con el nº 1""" //---------------------------------------------------------------// ++++++CHEQUEAMOS LOS INTERRUPTORES DE GRABAR Y SECUENCIAR+++++

if ((digitalRead (Interruptor_grabar)== HIGH) and digitalRead (Interruptor_secuenciar)== HIGH) 43


{ //-------color del Led RGB AMARILLO cuando -------//-----Interruptor_secuenciar)== HIGH --> SecuenciaranalogWrite(rojo,240); analogWrite(verde,245); analogWrite(azul,7); //------------------------------} // ---- CONTROL INTERRUPTOR 7 de Grabación -------if ((digitalRead(Interruptor_grabar) == LOW)and (FlagGrabar) == 0) //pin 7 a cero para grabar movimientos { StopMotores(); // para los motores todos llevan 200 ms //poner todos los motores parados hacer rutina Serial.println("pin 7 a cero Grabar_movimientos"); //mensaje y retorno a la posicion inical de 90º tarda 5 a 6 sgdos. Mensaje_Retorno_Posicion() ; // o mejor poner aquí mensaje de grabacion +++++++********** //----lo primero borrar el anterior archivo de secuencias de movimiento--SD.remove("posicmot.txt"); miarchivo = SD.open("posicmot.txt", FILE_WRITE);//nombre del archivo con los pasos grabados FlagGrabar = 1; //flag de que se está grabando y no repetir funcion } // Fin del if (Interruptor_grabar == 0) if (digitalRead(Interruptor_grabar) == LOW) { valorPotX = analogRead (pinAnalogico+5);//al Joystic A0 le corresponde el Potenciometro A5 valorPotX = map (valorPotX,0,1023,0,180); Grabar(valorPotX,letra); // ir a grabar y luego mover los motores con joystick } // fin del if (digitalRead((Interruptor_grabar) == LOW) if ((digitalRead (Interruptor_grabar)== HIGH)and (FlagGrabar) == 1)//para que no cierre más el archivo { StopMotores(); //hay en él un delay de 200ms por lo que no es necesario el debounce miarchivo.close(); //Cuando levante esperar 100 ms para el dobounce y cerrar archivo FlagGrabar = 0; // Iniciamos el flag }

apagarLeds ();

// ---- CONTROL INTERRUPTOR 8 de Secuenciar -------//Si pin 8 a cero ir a secuenciar-movimiento if ((digitalRead(Interruptor_secuenciar) == LOW)and (FlagSecuenciar) == 0) { StopMotores(); //hay en él un delay de 200ms por lo que no es necesario el deobunce Serial.println("pin 8 a cero Secuenciar_movimientos"); Mensaje_Retorno_Posicion() ; // o mejor poner aquí mensaje de grabacion +++++++********** FlagSecuenciar = 1; //flag de que se está secuenciando y no repetir funcion

44


} // Fin del if (digitalRead((Interruptor_secuenciar) == LOW)and (FlagSecuenciar == 0)) if (digitalRead(Interruptor_secuenciar) == LOW) { Secuenciar_movimientos(); // si interruptor 8 a cero; "Secuenciar_movimientos()" } // fin del if (digitalRead((Interruptor_secuenciar) == LOW)) if ((digitalRead (Interruptor_secuenciar)== HIGH)and (FlagSecuenciar) == 1)//para que no cierre más el archivo { StopMotores(); //hay en él un delay de 200ms por lo que no es necesario el deobunce miarchivo.close(); FlagSecuenciar = 0; // Iniciamos el flag }

apagarLeds();

//---------------------------------------------------//------ INSTRUCCIONES PARA MOVER LOS MOTORES CON LOS JOYSTICK --Serial.print ("Joystick sensor "); Serial.print (pinAnalogico); Serial.print (" "); Serial.print (servoVal); Serial.println (" Grados"); // --CON EL FIN DE MEJOR CONTROL DE LA PINZA motor 1--//--- reducir velocidad al cerrar y aumentar al abrir --int valorPWM = 180; //valor global para los motores if ((pinAnalogico) == 0) // si es el motor 1 velocidad 60 valorPWM = 80 ; // """AQUI LO DEJO EN 80 en lugar de 60 //Para que no se quede pillado al coger la pinza un objeto""" if ((pinAnalogico) == 1) // si es el motor 2 velocidad 150 valorPWM = 150 ; //para probar y garantizar manejo cómodo y el no bloqueo de la pinza valorPotX = analogRead (pinAnalogico+5);//al Joystick A0 le corresponde el Potenciometro A5 valorPotX = map (valorPotX,0,1023,0,180); delayMicroseconds(100);// 100 microsegundos para volver a leer analogRead (...) //-----------------------------------------------// Posición NEUTRA de los JOYSTICK un poco aumentada para //garantizar estabilidad de manejo. He comprobado que oscila //entre 87 a 92 pero por seguridad pongo 80 a 94. // "sin embargo los joystick de la ps2x mantiene un valor muy estable en 90" if (servoVal>= 80 and (servoVal <= 94)) { digitalWrite (int1,LOW); digitalWrite (int2,LOW); digitalWrite (pinPWM,LOW); Serial.print("ESTA EN POSICION "); Serial.println (servoVal); 45


} //--------------------------------------------if (servoVal < 80) { analogWrite (pinPWM,valorPWM); digitalWrite (int1,LOW); digitalWrite (int2,HIGH); } // -----Para evitar bloqueo por llegar a extremos Para M1 y M5 ------// evita bloqueo excesivamente pinza cerrada, tiende a ABRIR pinza if ((valorPotX > 114) and (pinAnalogico == 0)) { //tiende a abrir para evitar bloqueo M1 analogWrite (pinPWM,90); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } // evita que el M5 choque con patilla Potenciometro 5 margen 70º izda a 121º dcha if ((valorPotX > 120) and (pinAnalogico == 4)) { StopMotores();// para estabilizar y evitar que dañe potenciometro analogWrite (pinPWM,180); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } //-------------------------------------------------------------------if (servoVal > 94) { analogWrite (pinPWM,valorPWM); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } // -----Para evitar bloqueo por llegar a extremos Para M1 y M5 ------// evita bloqueo pinza excesivamente abierta, tiende a CERRAR pinza if ((valorPotX <= 57)and (pinAnalogico == 0)) { analogWrite (pinPWM,90); digitalWrite (int1,LOW); digitalWrite (int2,HIGH); } // evita que el M5 choque con patilla Potenciometro 5 margen real 63 izda a 127 dcha // aunque ponga 70º a 120º para tener mas garantía por las inercias. 46


if ((valorPotX < 70)and (pinAnalogico == 4)) { analogWrite (pinPWM,180); // se podrĂ­a quizas mejor poner antes StopMotores()*** digitalWrite (int1,LOW); digitalWrite (int2,HIGH); } //-------------------------------------------------------------------} // fin de la funcion JoystickPS2X (...) //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// ---------------------------------------------------------//-----------FUNCIĂ“N ir a Posicion HOME --------------------int Home (int PotMotorX,String motor,int pinPWM,int int1,int int2) // ---------------------------------------------------------{ int servoVal = analogRead (PotMotorX); servoVal = map (servoVal,0,1023,0,180); delayMicroseconds(100); // tiempo entre lecturas 0,1 ms Serial.print (motor); Serial.print (" "); Serial.print (servoVal); Serial.println (" Grados"); int valorPWM = 180; //valor Global para los motores salvo para el 1 y 2 if (motor == "motor 1") { valorPWM = 60; } if (motor == "motor 2") { valorPWM = 150; } while (1) { servoVal = analogRead (PotMotorX); delayMicroseconds(100); servoVal = map (servoVal,0,1023,0,180); //-----------------------Serial.print (motor); Serial.print (" "); Serial.print (servoVal); Serial.println (" Grados"); //-----------------------47


if ((servoVal>= 89)and (servoVal <= 91)) //Como veo q esta muy estable pondre 89 a 91 { digitalWrite (pinPWM,LOW); digitalWrite (int1,LOW); digitalWrite (int2,LOW); Serial.print("ESTA EN POSICION "); Serial.println (servoVal); delay(200); //de nuevo analizar y actuar en consonancia: //si estรก entre 89 a 91 salir de lo contrario continuar servoVal = analogRead (PotMotorX); delayMicroseconds(100); servoVal = map (servoVal,0,1023,0,180); } if ((servoVal >= 89)and (servoVal <= 91)) { break; //salir } if (servoVal < 83) // velocidad giro grande { analogWrite (pinPWM,valorPWM); digitalWrite (int1,LOW); digitalWrite (int2,HIGH); } if ((servoVal >= 83) and (servoVal < 89) and (motor == "motor 1")) // REDUCIR VELOCIDAD { analogWrite (pinPWM,40); digitalWrite (int1,LOW); digitalWrite (int2,HIGH); } if ((servoVal >= 83) and (servoVal < 89) and (motor == "motor 2")) // REDUCIR VELOCIDAD **** { analogWrite (pinPWM,100); digitalWrite (int1,LOW); digitalWrite (int2,HIGH); } if ((servoVal >= 83) and (servoVal < 89) and (motor != "motor 1")and (motor != "motor 2")) // REDUCIR VELOCIDAD { analogWrite (pinPWM,110); digitalWrite (int1,LOW); 48


digitalWrite (int2,HIGH); } if ((servoVal > 95)) { analogWrite (pinPWM,valorPWM); //velocidad giro grande digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } if ((servoVal >= 92)and(servoVal <= 95) and (motor == "motor 1")) { analogWrite (pinPWM,40); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } if ((servoVal >= 92)and(servoVal <= 95) and (motor == "motor 2")) { analogWrite (pinPWM,100); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } if ((servoVal >= 92) and (servoVal <= 95)and (motor != "motor 1")and (motor != "motor 2")) { analogWrite (pinPWM,110); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } }//fin del while } // fin de la funcion Home //--------------------------------------------------------//-------FunciĂłn de Stop Paro de Todos los motors---------//--------------------------------------------------------void StopMotores () { int i = 0; digitalWrite (2,LOW);// PONE A 0 las seĂąales PWM de los enables motores digitalWrite (3,LOW); digitalWrite (5,LOW); digitalWrite (6,LOW); digitalWrite (7,LOW); for (i=0; i<10; i++) { digitalWrite((22+i),LOW); // Pone a cero de la salida 22 a la 31 } // fin del for (i=0; i<10; i ++) 49


delay(200); //tiempo que da para que paren todos } // fin de la funcion void StopMotores //--------------------------------------------------------//-- Función con mensaje que va a retornar a la -----//-----------posición inical de 89º a 91º------------void Mensaje_Retorno_Posicion() //----------------------------------------------------{ ledRojo(); //activar el led rojo mientras se va a Home, tambien se mantiene //en la Secuenciar_movimientos() Serial.println ("El brazo ira a posicion inicial 90 grados"); Serial.println ("despues de 5 segundos mover Joystick"); delay (5000); //tiempo para comenzar a utilizar el Joystick o efecturar el secuenciador //------Desplazar los ejes a "Home (.......) -----------///int Home (int PotMotorX,String motor,int pinPWM,int int1,int int2) Home (9,"motor 5",6,30,31); //Preferible en primer lugar el motor 5 giro transversal // se evita que si el M4 esta muy bajo y el giro del 5 es grande //choque el la columna del M4 con el potenciometro del M5 Home (5,"motor 1",2,22,23); //Motor 1 Home (6,"motor 2",3,24,25); //Motor 2 Home (7,"motor 3",4,26,27); //Motor 3 Home (8,"motor 4",5,28,29); //Motor 4 //------------------------------------------------------} // fin void Mensaje_Retorno_Posicion() //------FUNCIÓN para GRABAR EN SD las posicones de los SERVOS -----int Grabar(int valor,char letra) //-----------------------------------------------------------------{ if (miarchivo != 0) // si se abre; grabar { ledVerde(); //activar Led Verde //NO UTILIZO miarchivo.write(servoVal); porque los enteros no se ven //luego escritos en la SD mas que como signos raros. Y no me gusta //aun siendo más fácil su uso miarchivo.print(valor);//valor_a_grabar. El nº 123 se escribe como '1' '2' '3' miarchivo.print(letra); miarchivo.println(); //el 13 y el 10 retorno y cambio linea finalizan la copia de cada posición Serial.print(" VALOR SD; "); 50


Serial.print(valor); // (valor_a_grabar); Serial.println(letra); }//fin del if (miarchivo != 0) }// Fin funcion Grabar //-------------------------------------------------------------------//FUNCIÓN para secuenciar los movimientos void Secuenciar_movimientos() //-------------------------------------------------------------------{ //Ya están declaradas como globales String valorString = ""; //Valor para convertir más tarde a decimal entero int valorInt = 0 ; //para iniciar su valor NO BORRAR char c ; //nombre del archivo con los pasos grabados miarchivo = SD.open("posicmot.txt"); // si se abre OK leer todas las posiciones grabadas en la SD if (miarchivo != 0) { ledAzul(); //activar el led azul en Secuenciar_movimientos() while (miarchivo.available() > 0) { //Lee las posiciones de los motores grabadas en la SD // en la SD está guardado el ENTERO como ASCII con la instruccion miarchivo.print(servoVal). //El valor ASCII de la SD lo paso a int servoVal //para ver cuando se pulsa enter 13D o nueva linea 10D servoVal = (miarchivo.read()); c = char(servoVal); // pasa a carácter el valor decimal // también son decimales el 13-10 enter y nueva linea //que es lo que separa cada posción guardada en SD //NO CONCATENAR dichos valores if ((servoVal!=13)and (servoVal!=10))// { //---------------------valorString.concat(c);// //"*.toInt()pasa una cadena de caracteres a un numero entero // ejemplo 123abc23 lo transforma en el entero 123 valorInt = valorString.toInt(); 51


//---------------------}// fin del if ((miarchivo.read()== 13)and (miarchivo.read()== 10)) //Al llegar al cambio de lĂ­nea activar el motor if (c == 'A')//Cuando sea cambio linea { Serial.print("Secuenciar MOTOR 1 "); Serial.print(valorInt); //imprimir en el Serial para ver los valores Serial.println('A'); //int ActivarMotores ( int potMotorX,int valorInt,int pinPWM,int int1, int int2) ActivarMotores(5,valorInt,2,22,23); // para activar el Motor 1 valorString = "" ; //iniciar la variable. // NOTA no es necesario reiniciar "valorInt" al haber reiniciado: valorString = "" ; } //fin del if (c == 'A') if (c == 'B')//Cuando sea cambio linea { Serial.print("Secuenciar MOTOR 2 "); Serial.print(valorInt); //imprimir en el Serial para ver los valores Serial.println('B'); ActivarMotores(6,valorInt,3,24,25); // para activar el Motor 2 valorString = "" ; } //fin del if (c == 'B') if (c == 'C')//Cuando sea cambio linea { Serial.print("Secuenciar MOTOR 3 "); Serial.print(valorInt); //imprimir en el Serial para ver los valores Serial.println('C'); ActivarMotores(7,valorInt,4,26,27); // para activar el Motor 3 valorString = "" ; } //fin del if (c == 'C') if (c == 'D')//Cuando sea cambio linea { Serial.print("Secuenciar MOTOR 4 "); Serial.print(valorInt); //imprimir en el Serial para ver los valores Serial.println('D'); ActivarMotores(8,valorInt,5,28,29); // para activar el Motor 4 52


valorString = "" ; } //fin del if (c == 'D') if (c == 'E')//Cuando sea cambio linea { Serial.print("Secuenciar MOTOR 5 "); Serial.print(valorInt); //imprimir en el Serial para ver los valores Serial.println('E'); ActivarMotores(9,valorInt,6,30,31); // para activar el Motor 5 valorString = "" ; } //fin del if (c == 'E') if (digitalRead(Interruptor_secuenciar) == HIGH) { FlagSecuenciar = 0; //reiniciamos el flag. break; //salir del while. }//FIN del if (digitalRead(Interruptor_secuenciar) == HIGH) } //fin del While miarchivo.available... // Cuando se hayan leído todos los datos del archivo cerrarlo //y salir de la funcion secuenciar_movimientos StopMotores(); miarchivo.close();//cierra el archivo }//fin del if (miarchivo != 0) } //fin del void Secuenciar_movimientos(); // ----FUNCION "ActivarMotores" para activar los motores ---------int ActivarMotores (int PotMotorX,int valorInt,int pinPWM,int int1,int int2) //----------------------------------------------------------------{ int valorPWM = 200; // para el resto de actuaciones a velocidad de 200 if (PotMotorX == 5) // se trata del potenciómetro del motor 1 pinzas { valorPWM = 60; } if (PotMotorX == 6) // se trata del potenciómetro del motor 2 { valorPWM = 170; 53


} if (PotMotorX == 9) // se trata del potenciómetro del motor 5 { valorPWM = 200; // "lo podria suprimir se utilizaría el valor global valorPWM = 200" } //lo utilizo para que no se repitan ciclos innecesarios int valorAnterior = 0 ; while (1) { //1º se leen la posición del potenciómetro de los motores //para comparar después con el que debe tener servoVal = analogRead (PotMotorX); delayMicroseconds(100); servoVal = map (servoVal,0,1023,0,180); if (servoVal != valorAnterior) //para evitar repetir ciclos { //-----------------------Serial.print ("motor: "); Serial.print (PotMotorX); //motor 0 a 4 Serial.print ("--"); Serial.print (servoVal); Serial.println (" Grados"); //-----------------------if (abs(servoVal - valorInt) < 2) // Para dar una histéresis de +-1º { digitalWrite (pinPWM,LOW); digitalWrite (int1,LOW); digitalWrite (int2,LOW); Serial.print("ESTA EN POSICION "); Serial.println (servoVal); //// stopMotores(); //podría quizas emplearlo pero prefiero hacerlo así // De nuevo analizar y actuar en consonancia: si está +-1º respecto al valor // que debe tener salir de lo contrario continuar servoVal = analogRead (PotMotorX); delayMicroseconds(100); servoVal = map (servoVal,0,1023,0,180); } if (abs(servoVal - valorInt) <= 2) // Para dar una histéresis de +-1º { digitalWrite (pinPWM,LOW); digitalWrite (int1,LOW); 54


digitalWrite (int2,LOW); //StopMotores(); break; //salir } if (servoVal < (valorInt-7)) { analogWrite (pinPWM,valorPWM); digitalWrite (int1,LOW); digitalWrite (int2,HIGH); }

//PARA REDUCIR VELOCIDAD AL M 1 if (servoVal >= (valorInt-7)and (servoVal< valorInt)and (PotMotorX == 5)) { analogWrite (pinPWM,40); digitalWrite (int1,LOW); digitalWrite (int2,HIGH); }

//el resto de motores a velocidad 110 if (servoVal >= (valorInt-7)and (servoVal< valorInt)and (PotMotorX != 5)) { analogWrite (pinPWM,110); digitalWrite (int1,LOW); digitalWrite (int2,HIGH); } if (servoVal > (valorInt+7)) // si es MAYOR HIGH/LOW { analogWrite (pinPWM,valorPWM); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } // El PotMotorX == 5 es el Motor 1 if (servoVal <= (valorInt+7)and (servoVal >= (valorInt+1)and (PotMotorX == 5))) // +1 para compensacion { //se puede suprimir el +1 analogWrite (pinPWM,40); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } //Resto de los Motores a velocidad de 110 if (servoVal <= (valorInt+7)and (servoVal >= (valorInt+1)and (PotMotorX != 5))) // +1 para compensacion { //se puede suprimir el +1 analogWrite (pinPWM,110); digitalWrite (int1,HIGH); digitalWrite (int2,LOW); } 55


} // Fin del if (servoVal != valorAnterior) valorAnterior = servoVal; }//fin del while } // fin de la funcion Activar movimientos //------------------------------void setup() { //--------------------------------// pin 7 y 8 como entradas pinMode (Interruptor_grabar,INPUT); // Pin 7 como entrada nivel 0 para grabar movimiento pinMode (Interruptor_secuenciar,INPUT); // Pin 8 como entrada nivel 0 para secuenciar //el movimiento grabado pinMode (Interruptor_PS2X_Joystick,INPUT); // Pin 12 como entrada, nivel (0) manejo del brazo con JOYSTICK // de la mesa de control. A nivel (1) control desde mando PlayStatión PS2X pinMode(rojo,OUTPUT); //LED rojo pin 9 salida pinMode(verde,OUTPUT); //LED verde pin 10 salida pinMode(azul,OUTPUT); //LED azul pin 11 salida // Control L298N del Motor 1 pinMode(ENA_1, OUTPUT); //pin 2 señal PWM pinMode(IN1_1, OUTPUT); //pin 22 pinMode(IN2_1, OUTPUT); //pin 23 // Control L298N del Motor 2 pinMode(ENA_2, OUTPUT); //pin 3 señal PWM pinMode(IN1_2, OUTPUT); //pin 24 pinMode(IN2_2, OUTPUT); //pin 25 // Control L298N del Motor 3 pinMode(ENA_3, OUTPUT); //pin 4 señal PWM pinMode(IN1_3, OUTPUT); //pin 26 pinMode(IN2_3, OUTPUT); //pin 27 // Control L298N del Motor 4 pinMode(ENA_4, OUTPUT); //pin 5 señal PWM pinMode(IN1_4, OUTPUT); //pin 28 pinMode(IN2_4, OUTPUT); //pin 29 // Control L298N del Motor 5 pinMode(ENA_5, OUTPUT); //pin 6 señal PWM pinMode(IN1_5, OUTPUT); //pin 30 pinMode(IN2_5, OUTPUT); //pin 31 // --PARA EL led como salida---pinMode (led, OUTPUT) ; // pin 18 como salida para led iluminador del brazo digitalWrite (led, LOW) ; // lo inicio en nivel bajo. Se puede activar desde 56


//-----------------------------

//mando de la play tecla azul (X) y desactivar con tecla roja (0)

//inicio con todos apagados apagarLeds(); //nota tengo en el pin 9 el rojo 10 el verde //y 11 el azul // -----POSICION INICIAL MOTORES DESCONECTADOS------digitalWrite (ENA_1,LOW) ; //Desconectar motor1 digitalWrite (IN1_1,LOW); digitalWrite (IN2_1,LOW); digitalWrite (ENA_2,LOW) ; //Desconectar motor2 digitalWrite (IN1_2,LOW); digitalWrite (IN2_2,LOW); digitalWrite (ENA_3,LOW) ; //Desconectar motor3 digitalWrite (IN1_3,LOW); digitalWrite (IN2_3,LOW); digitalWrite (ENA_4,LOW) ; //Desconectar motor4 digitalWrite (IN1_4,LOW); digitalWrite (IN2_4,LOW); digitalWrite (ENA_5,LOW) ; //Desconectar motor4 digitalWrite (IN1_5,LOW); digitalWrite (IN2_5,LOW); //---------------------------------------------------//Inicializamos la conexión serial Serial.begin(57600); //----------------- MÓDULO RECEPTOR ACTIVO ??? ----------------//-----------------------------------------------------------// En mi ps2x chino debo hacer el ps2x.config_gamepa(…) //doblemente para que sea reconocido el módulo receptor ps2x //------------------------------------------------------------error = ps2x.config_gamepad(14,15,16,17, true, true); //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error delay(50); // este delay se puede suprimir pero mejor dejarlo error = ps2x.config_gamepad(14,15,16,17, true, true); //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error delay(50); // “Este delay, no se puede suprimir aunque sí bajar el tiempo lo tengo probado.” if(error == 0){ Serial.println("Controlador PS2X, configurado EXITOSAMENTE"); } else if(error == 1) 57


Serial.println("Controlador PS2X NO encontrado"); else if(error == 2) Serial.println("Controlador PS2X encontrado, pero no acepta comandos"); else if(error == 3) Serial.println("Controller refusing to enter Pressures mode, may not support it. "); type = ps2x.readType(); switch(type) { case 0: Serial.println("Unknown Controller type"); break; case 1: Serial.println("DualShock Controller Found"); break; } //--------------------------------------------------------//+++++ LECTURA DE LA TARJETA SI NO ESTÁ INSERTADA SE QUEDA A LA ESPERA +++++++++++++ //pinMode(53,OUTPUT);//Necesario para la librería SD(en la MEGA el 53 y en la UNO el 10 //ponerlo como salida aunque no se utilice para compatibilizarlo con la UNO //HE PROBADO QUE INCLUSO SIN PONERLOS VA OK. pinMode(10,OUTPUT); pinMode(53,OUTPUT);//Necesario para la librería SD en Arduino Mega 2560 Serial.print("Inicializando SD card..."); // ---SE QUEDA A LA ESPERA DE TENER BIEN LA TARJETA.--//el pin cs en la mega es el 53 y en la uno el 10 en la ethernet el 4 if (SD.begin(53)== 0) { Serial.println ("Error de lectura en SD o bien; no hay Tarjeta"); while (SD.begin(53)== 0)//cuando sea 1 salir { //Buble infinito hasta que se inserte tarjeta SD ledRojo(); //activar led rojo delay(250); apagarLeds(); delay(250); } } //fin del if (SD.begin(53)== 0) //Si llega hasta aquí se ha abierto OK la tarjeta SD // ES OBLIGATORIO TENER SD introducida aunque NO LA UTILICEMOS Serial.println ("Iniciacion de SD correcta"); 58


} //Fin void setup() //--------------------------------------------------------void loop() //--------------------------------------------------------{ // mensaje y desplazamiento a home Mensaje_Retorno_Posicion (); //--- AQUÍ ESTARÍAN LAS INSTRUCCIONES PARA hacer pruebas--// con los Joystic y los potenciómetros. /* */ //***las tengo al final del programa por si me hicieran // de nuevo falta con los nº 2 y 3 ****** //---------------------------------------------------------while (1) // Bucle infinito. { // pin analogico lectura Joystick + pin PWM activacion driver + pin giro + pin giro (dcha/izqda) // por defecto ,(a nivel HIGH )está pensado para que sea manejado el brazo robótico desde el //mando de la playStation (PS2X) // y a (nivel LOW) desde los Joystick de la mesa controladora. //+++ los valores para CONTROL DESDE EL MANDO DE LA PS2X ++++ if (digitalRead(Interruptor_PS2X_Joystick)== HIGH) { //-----Debe haber al menos una lectura del módulo cada segundo.----ps2x.read_gamepad(); //----------------------------------------------------------------JoystickPS2X(PSS_LY,0,2,22,23,'A'); //motor 1 (pinza)le asigno A al motor 1 JoystickPS2X(PSS_LX,1,3,24,25,'B'); //motor 2 le asigno B al motor 2 JoystickPS2X(PSS_RY,2,4,26,27,'C'); //motor 3 le asigno C al motor 3 JoystickPS2X(PSS_RX,3,5,28,29,'D'); //motor 4 le asigno D al motor 4 //-----------------------------------------------------------------------// --Para el control del quinto motor con los pulsadores // PSB_PAD_RIGHT Y LEFT que mientras no se pulsen se lee valor 0 y al ser //pulsados su valor analógico oscila de 0 a 255. //-----------------------------------------------------------------------JoystickPS2X(PSAB_PAD_RIGHT,4,6,30,31,'E'); //motor 5 le asigno E al motor 5 NADA MÁS PUEDO CONTROLAR //4 MOTORES por sólo tener el mando 2 potenciómetros delay(35); // necesario poner para dar tiempo activación motor 5 y no 59


//se frene con el otro pulsador "PSAB_PAD_LEFT" que en reposo tiene valor 0 JoystickPS2X(PSAB_PAD_LEFT,4,6,30,31,'E'); //motor 5 le asigno E al motor 5 NADA MÁS PUEDO CONTROLAR // 4 MOTORES por sólo tener el mando 2 potenciómetros // aquí no es necesario ningún delay } //+++ los valores para control desde los JOYSTICK mesa controladora ++++ //PONGO 15 como valorPSS por seguridad que no hay nada con esa numeración //en los comandos del mando de la playStation //+++ los valores para CONTROL DESDE LOS JOYSTICK DE LA MESA ++++ if (digitalRead(Interruptor_PS2X_Joystick)== LOW) { JoystickPS2X(15,0,2,22,23,'A'); //motor 1 (pinza)le asigno A al motor 1 JoystickPS2X(15,1,3,24,25,'B'); //motor 2 le asigno B al motor 2 JoystickPS2X(15,2,4,26,27,'C'); //motor 3 le asigno C al motor 3 JoystickPS2X(15,3,5,28,29,'D'); //motor 4 le asigno D al motor 4 JoystickPS2X(15,4,6,30,31,'E'); //motor 5 le asigno E al motor 5 } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ } //fin del While (1) } //fin del void loop()

// ---------- F I N D E L P R O G R A M A ----------------// AQUÍ PONGO INSTRUCCIONES QUE ME HAN AYUDADO EN EL PROGRAMA. /* //1ª /* // IRÍA COLOCADO AL COMIENZO DE LA FUNCIÓN int Joystic (....) //--------PARA DETECTAR PROBLEMA EN LECTURA INTERRUPTORES--while (1) // para comprobar si hay ruido. era debido al doble parentesis que tenian los if //mal if (digitalRead((Interruptor_grabar) == LOW))este provocaba que se activase tanto por low como por high sin mas. //mal if (digitalRead(Interruptor_grabar == LOW)) // bien if (digitalRead(Interruptor_grabar) == LOW) { if (digitalRead(Interruptor_grabar) == LOW) { Serial.println("pin 8 a cero Grabar_movimientos"); delay(1000); } if (digitalRead(Interruptor_grabar) == HIGH) { Serial.println("pin 8 a HIGH"); delay(1000); 60


} } //fin del while de prueba */ //---------------------------------------------------// INSTRUCCIONESW 2ยบ Y 3ยบ colocadas al comienzo de la funciรณn void Loop () /* // 2ยบ PARA LOS JOYSTIC ""NO BORRAR para hacer pruebas"" while (1) { servoVal = analogRead (0); servoVal = map(servoVal,0,1023,0,179); Serial.print("JOYSTICK 1 "); Serial.println(servoVal); delay(3000); servoVal = analogRead (1); servoVal = map(servoVal,0,1023,0,179); Serial.print("JOYSTICK 2 "); Serial.println(servoVal); delay(3000); servoVal = analogRead (2); servoVal = map(servoVal,0,1023,0,179); Serial.print("JOYSTICK 3 "); Serial.println(servoVal); delay(3000); servoVal = analogRead (3); servoVal = map(servoVal,0,1023,0,179); Serial.print("JOYSTICK 4 "); Serial.println(servoVal); delay(3000); servoVal = analogRead (4); servoVal = map(servoVal,0,1023,0,179); Serial.print("JOYSTICK 5 "); Serial.println(servoVal); delay(3000); } */ /* // 3ยบ PARA LOS POTENCIOMETROS ""NO BORRAR para hacer pruebas"" while (1) { servoVal = analogRead (5); // servoVal = map(servoVal,0,1023,0,179); Serial.print("MOTOR 1 "); Serial.println(servoVal); delay(2000); servoVal = analogRead (6);// 61


servoVal = map(servoVal,0,1023,0,179); Serial.print("MOTOR 2 "); Serial.println(servoVal); delay(2000); servoVal = analogRead (7); servoVal = map(servoVal,0,1023,0,179); Serial.print("MOTOR 3 "); Serial.println(servoVal); delay(2000); servoVal = analogRead (8); servoVal = map(servoVal,0,1023,0,179); Serial.print("MOTOR 4 "); Serial.println(servoVal); delay(2000); servoVal = analogRead (9); servoVal = map(servoVal,0,1023,0,179); Serial.print("MOTOR 5 "); Serial.println(servoVal); delay(2000); } */ TUTORIAL USO DRIVER DUAL L298 PARA MOTORES DC y paso a paso ESTA ES LA MISMA PLACA QUE COMPRE EN ALIEXPRESSS. http://electronilab.co/tutoriales/tutorial-de-uso-driver-dual-l298n-para-motores-dc-y-paso-a-paso-con-arduino/

Tutorial: Uso de Driver L298N para motores DC y paso a paso con Arduino El siguiente tutorial está basado en el Driver dual para motores (Full-Bridge) – L298N, ofrecido por ELECTRONILAB.CO. Puedes adquirir este módulo en nuestra tienda. Este módulo basado en el chip L298N te permite controlar dos motores de corriente continua o un motor paso a paso bipolar de hasta 2 amperios. El módulo cuenta con todos los componentes necesarios para funcionar sin necesidad de elementos adicionales, entre ellos diodos de protección y un regulador LM7805 que suministra 5V a la parte lógica del integrado L298N. Cuenta con jumpers de selección para habilitar cada una de las salidas del módulo (A y B). La salida A esta conformada por OUT1y OUT2 La salida B por OUT3 y OUT4. Los pines de habilitación son ENA y ENB respectivamente.deben estar a nivel alto para estar operativo Echemos un vistazo a cómo controlar sólo uno de los motores, Motor1. Con el fin de activar el motor, la línea ENABLE1 debe ser alta. A continuación, controlar el motor y su dirección mediante la aplicación de una señal LOW o HIGH a las líneas Input1 y INPUT2, como se muestra en esta tabla. Input1 Input2 Acción Roturas de motor y paradas * 0 0 El motor gira hacia adelante 1 0 El motor gira hacia atrás 0 1 Roturas de motor y paradas * 1 1 * Para costa un motor a una parada más lento, aplique una señal de baja a la línea ENABLE1.

62


En la parte inferior se encuentran los pines de control del módulo, marcados como IN1, IN2, IN3 e IN4. Conexión de alimentación Este módulo se puede alimentar de 2 maneras gracias al regulador integrado LM7805.

√ Cuando el jumper de selección de 5V se encuentra activo, el módulo permite una alimentación de entre 6V a 12V DC. Como el regulador se encuentra activo, el pin marcado como +5V tendrá un voltaje de 5V DC. Este voltaje se puede usar para alimentar la parte de control del módulo ya sea un microcontrolador o un Arduino, pero recomendamos que el consumo no sea mayor a 500 mA. √ Cuando el jumper de selección de 5V se encuentra inactivo, el módulo permite una alimentación de entre 12V a 35V DC. Como el regulador no está funcionando, tendremos que conectar el pin de +5V a una tensión de 5V para alimentar la parte lógica del L298N. Usualmente esta tensión es la misma de la parte de control, ya sea un microcontrolador o Arduino. -------------------------------------------------- 0 -----------------------------------------------http://electronilab.co/tienda/driver-dual-para-motores-full-bridge-l298n/

Descripción del Producto 63


Este módulo es el complemento ideal para proyectos de robótica y Router CNC.Permite controlar hasta 2 motores de corriente continua o un motor paso a paso bipolar. También permite controlar un motor paso a paso unipolar configurado como bipolar de forma muy sencilla y eficaz. . Características •

Voltaje de alimentación, mínimo de 5 V. Posee dos entradas, una de 5V para controlar la parte lógica y otra para alimentar las salidas al motor, que pueden ser de 5V o más.

La tarjeta tiene la opción de habilitar un regulador LM7805 integrado en ella para alimentar la parte lógica con lo que se puede alimentar la tarjeta con 12V por ejemplo.

Corriente máxima 2 Amperios.

Posee 6 entradas de control (ver tabla de control)

Admite entradas de señal PWM para el control de velocidad.

Dimensiones: 43 mm x 23,9 mm x 43 mm.

Salidas: para 2 motores de DC o para un motor bipolar paso a paso. Partes

Esquema

64


Más información: •

Hoja de datos (datasheet)

Código de ejemplo

65


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.