Community project

Portero Robótico Desviador De Pelotas

Photo of Portero Robótico Desviador De Pelotas
Generated with AI

Guillermo Campos Ornelas

Published November 5, 2026

This robotic ball deflector combines precise motor control with solenoid-based striking to create an automated sports training device. Built around an Arduino Uno, it uses a PS2 joystick for lateral positioning via a NEMA 17 stepper motor, while an independent 12V solenoid delivers timed strikes. The guide provides a complete wiring diagram, parts list with fused power distribution, and firmware with debounced firing logic and acceleration profiles.

Assembly progresses from joystick calibration through power protection and motor setup, then integrates the solenoid strike mechanism with safety interlocks. Testing begins without load to verify motor direction and solenoid timing, then proceeds with the full mechanical assembly. Builders will learn stepper motor control, relay switching for high-current loads, and real-time input handling on a microcontroller.

Wiring diagram

Loading diagram…

Gather all the parts

QtyComponent
1

PS2 Joystick Module (KY-023)

Two-axis analog thumb joystick module (KY-023 / PS2 style) with a push switch under the stick. Two 10 kOhm potentiometers give X and Y voltages that sit near half the supply at rest, and pressing the stick operates a digital switch. It runs from 3.3 to 5 V and connects through a five-pin GND, +5V, VRx, VRy, SW right-angle header.

1

Pololu A4988 Black Edition con disipador

VMOT 12 V separado de VDD 5 V. Entradas STEP DIR EN a 5 V. Referencia https://www.pololu.com/product/2128

1

Nema 17

12 V; 1.5 A/fase; bipolar

NEMA 17-size bipolar stepper motor for motion axes. Typical hobby modules are 42mm-frame, 4-wire/two-phase motors with 1.8 degree step angle (200 steps/rev); use with a current-limited stepper driver such as TMC2209/A4988/DRV8825 rather than direct GPIO.

1

IRLZ44N Logic-Level N-Channel MOSFET

Logic-level N-channel MOSFET commonly used as a low-side switch for DC loads from 3.3V or 5V microcontroller GPIO. Use a gate resistor, a gate pulldown, and a flyback diode for inductive loads.

1

Microswitch COM NC NO

COM y NC conectados; NO libre.

1

Microswitch COM NC NO

COM y NC conectados; NO libre.

1

24v Buck Converter

Salida ajustada a 8 V

LM2596-based adjustable step-down buck converter module. Commonly used to regulate a higher battery rail, such as a 2S 18650 pack, down to 5V for Arduino logic. It is a regulator, not a charger or battery protection board.

1

Electrolytic Capacitor

220 µF / 35 V

Radial aluminium electrolytic capacitor bought by value and voltage rating, such as 10 µF, 100 µF or 1000 µF 10 V. It is polarised: the + lead goes to the higher voltage and the - lead, marked by the stripe on the sleeve, to the lower voltage or ground. It is mostly used for bulk filtering across a power rail, with a voltage rating comfortably above the rail.

1

Fuente regulada aislada 12 V / 5 A

Adaptador cerrado con salida DC; no trabajar en la red eléctrica.

1

Solenoide de golpe 12 V, máximo 2 A

Retorno por resorte; seleccionar fuerza hasta 20 N al recorrido necesario. La fuerza no se deduce del consumo; verificar ficha antes de comprar.

1

1N5822 Schottky 3 A / 40 V

Banda = cátodo K; protección en paralelo con bobina.

1

Fusible T5 A, ≥32 VDC con portafusible

Fusible T5 A, ≥32 VDC con portafusible; conectar según el esquema.

1

Fusible T3.15 A, ≥32 VDC con portafusible

Fusible T3.15 A, ≥32 VDC con portafusible; conectar según el esquema.

1

Fusible T2.5 A, ≥32 VDC con portafusible

Fusible T2.5 A, ≥32 VDC con portafusible; conectar según el esquema.

1

Interruptor general SPST ≥10 A / 24 VDC

Interruptor general SPST ≥10 A / 24 VDC; conectar según el esquema.

1

Resistencia 220 Ω / 0.25 W

Resistencia 220 Ω / 0.25 W; conectar según el esquema.

1

Resistencia 10 kΩ / 0.25 W

Resistencia 10 kΩ / 0.25 W; conectar según el esquema.

1

Resistencia 10 kΩ / 0.25 W

Resistencia 10 kΩ / 0.25 W; conectar según el esquema.

Assemble it in 10 steps

1. Joystick

Bloque «Joystick»: mando por cable de cinco conductores. +5V a 5V, GND a GND, VRX a A0 (posición lateral), VRY a A1 (reservado), SW a D5 (botón contra GND). Mantener centrado al encender.

2. Arduino Uno y A4988

Bloque «Arduino Uno y A4988»: STEP a D2, DIR a D3, EN a D4; resistencia r_enable de 10 kΩ entre EN y 5V para deshabilitar durante el arranque. VDD a 5V, GND_2 a GND. Unir RST con SLP y con 5V. MS1/MS2/MS3 a GND: paso completo.

3. Alimentación protegida

Con todo desenchufado: positivo de la fuente de 12 V a fusible general T5 A, luego interruptor general. Desde su salida distribuir tres ramas: fusible motor T3.15 A hacia VMOT, fusible solenoide T2.5 A hacia bobina, y entrada positiva del buck. Negativo común en estrella. Usar cable flexible de potencia de 0.75 mm² y bornes; no pasar potencia por protoboard ni por el Arduino.

4. Ajustar los 8 V del Arduino

Sin conectar VIN, medir y ajustar salida del buck a 8.0 V. Apagar y conectar VOUT+ a VIN y VOUT- a GND. El joystick y la lógica reciben 5 V del Uno; nunca 12 V. Usar solamente la salida aislada de un adaptador cerrado.

5. Motor y solenoide: movimiento lateral

Bloque «Motor y solenoide», circuito MOTOR: NEMA 17 fijo mueve exclusivamente la banda GT2 del portero amarillo. Identificar con multímetro cada pareja de bobina, sin suponer colores: pareja A a 1A/1B y pareja B a 2A/2B. Condensador de 220 µF/35 V directamente entre VMOT (+) y GND de potencia (-), lo más cerca posible. Colocar disipador sin cortocircuitar terminales.

  • Nunca conectar o desconectar motor con alimentación; puede destruir el A4988. Condensador invertido puede reventar.

6. Limitar corriente antes de cargar

Ajustar el límite del A4988 según motor y refrigeración: empezar en 1 A. Para Pololu Black con Rs=0.068 Ω, VREF=8×Imax×Rs: 0.544 V para 1 A; máximo objetivo 0.816 V para límite de 1.5 A. No trasladar estos voltajes a clones con otra Rs. En paso completo circula aproximadamente 70% de Imax por bobina: no aumentar el límite por encima de 1.5 A para compensarlo. El disipador no garantiza servicio continuo a esa corriente; reducir corriente si hay calentamiento o paradas térmicas.

  • Motor y driver pueden quemar al tacto. Si el par a corriente reducida no basta, se requiere mejor refrigeración o rediseñar el driver.

7. Topes de seguridad normalmente cerrados

Izquierdo: NC a D8 y COM a GND; derecho: NC a D9 y COM a GND. Dejar NO sin conectar. Ajustar para abrir antes del tope mecánico, con margen de frenado. Cable roto también bloquea ese sentido. No son un sistema de seguridad certificado.

8. Motor y solenoide: golpe independiente

Circuito SOLENOIDE: positivo después del fusible T2.5 A a POS de bobina; RET al DRAIN del IRLZ44N. SOURCE a negativo común. D6 a resistencia 220 Ω y luego GATE; 10 kΩ entre GATE y SOURCE. Diodo 1N5822 directamente en bobina: banda/cátodo al POS, ánodo al RET/drenador. En IRLZ44N TO-220 frontal rotulado, patas abajo: GATE izquierda, DRAIN centro (también pestaña), SOURCE derecha. No confundir con IRFZ44N.

  • Invertir el diodo cortocircuita la alimentación al activar. Aislar la pestaña metálica del MOSFET: está conectada al drenador.

9. Montaje móvil y primera prueba

El solenoide va en el carro y solo golpea la pelota. Guiar su cable flexible con alivio de tracción para que no alcance banda ni ranura. Escoger solenoide de 12 V ≤2 A con fuerza y carrera especificadas: 20 N no está garantizado por consumir 2 A. Pulso inicial 60 ms, mínimo 1 segundo entre golpes; reducir si la ficha exige menor ciclo. Si la corriente nominal difiere de 2 A, revisar y redimensionar fuente, MOSFET, diodo y fusibles.

10. Verificación sin banda y luego con carga

Primero probar motor sin banda: joystick a la derecha debe girar en sentido de desplazamiento derecho. Accionar el final derecho debe impedir ese giro y permitir el contrario; repetir izquierdo. Si sentido invertido, apagar y permutar una sola pareja de bobina. Después montar banda y verificar a baja velocidad con manos fuera. Con ambos finales abiertos no debe moverse. Botón mantenido debe dar un solo golpe. Apagar interruptor para detener potencia; con USB conectado el Uno puede seguir encendido.

Review all connections

1. Connections between "fuente" and "Arduino"

FunctionfuenteArduino
powerPOS → Fusible T5 A, ≥32 VDC con portafusible 1EXT
groundNEGGND

2. Connections between "fusible_general" and "Arduino"

Functionfusible_generalArduino
data2 → Interruptor general SPST ≥10 A / 24 VDC 1EXT

3. Connections between "interruptor" and "Arduino"

FunctioninterruptorArduino
power212V

4. Connections between "fusible_motor" and "Arduino"

Functionfusible_motorArduino
power112V
data2 → Pololu A4988 Black Edition con disipador VMOTEXT

5. Connections between "driver" and "Arduino"

FunctiondriverArduino
groundGNDGND
powerVDD5V
groundGND_2GND
digitalSTEPGPIO 2
digitalDIRGPIO 3
digitalENGPIO 4
digitalRST → Pololu A4988 Black Edition con disipador SLPEXT
powerSLP5V
groundMS1GND
groundMS2GND
groundMS3GND
power1A → Nema 17 A+EXT
power1B → Nema 17 A-EXT
power2A → Nema 17 B+EXT
power2B → Nema 17 B-EXT

6. Connections between "condensador" and "Arduino"

FunctioncondensadorArduino
power+ → Pololu A4988 Black Edition con disipador VMOTEXT
ground- → Pololu A4988 Black Edition con disipador GNDEXT

7. Connections between "fusible_sol" and "Arduino"

Functionfusible_solArduino
power112V
data2 → Solenoide de golpe 12 V, máximo 2 A POSEXT

8. Connections between "solenoide" and "Arduino"

FunctionsolenoideArduino
dataRET → IRLZ44N Logic-Level N-Channel MOSFET DRAINEXT

9. Connections between "mosfet" and "Arduino"

FunctionmosfetArduino
groundSOURCEGND

10. Connections between "diodo" and "Arduino"

FunctiondiodoArduino
powerK → Solenoide de golpe 12 V, máximo 2 A POSEXT
dataA → Solenoide de golpe 12 V, máximo 2 A RETEXT

11. Connections between "r_gate" and "Arduino"

Functionr_gateArduino
data1GPIO 6
data2 → IRLZ44N Logic-Level N-Channel MOSFET GATEEXT

12. Connections between "r_down" and "Arduino"

Functionr_downArduino
data1 → IRLZ44N Logic-Level N-Channel MOSFET GATEEXT
ground2GND

13. Connections between "buck" and "Arduino"

FunctionbuckArduino
powerVIN+12V
groundVIN-GND
powerVOUT+VIN
groundVOUT-GND

14. Connections between "joystick" and "Arduino"

FunctionjoystickArduino
power+5V5V
groundGNDGND
analogVRXGPIO 14
analogVRYGPIO 15
digitalSWGPIO 5

15. Connections between "r_enable" and "Arduino"

Functionr_enableArduino
data1 → Pololu A4988 Black Edition con disipador ENEXT
power25V

16. Connections between "limite_izq" and "Arduino"

Functionlimite_izqArduino
digitalNCGPIO 8
groundCOMGND

17. Connections between "limite_der" and "Arduino"

Functionlimite_derArduino
digitalNCGPIO 9
groundCOMGND

Deploy the firmware

#include <Arduino.h>
constexpr uint8_t STEP=2, DIR=3, ENABLE=4, BUTTON=5, SOL=6, LEFT=8, RIGHT=9;
constexpr bool RIGHT_LEVEL=HIGH; // Verificar sin banda; invertir si gira al revés.
constexpr uint16_t PULSE_MS=60, COOLDOWN_MS=1000;
constexpr float MAX_SPEED=500.0f, ACCEL=700.0f;
int center=512;
float speed=0;
uint32_t updateMs=0, sampleMs=0, lastStep=0, shotStart=0, lastShot=0, buttonChange=0;
bool firing=false, everShot=false, rawPrev=true, stable=true, armed=false;
int axis=512;
void setup(){
 digitalWrite(SOL,LOW); pinMode(SOL,OUTPUT);
 digitalWrite(ENABLE,HIGH); pinMode(ENABLE,OUTPUT);
 pinMode(STEP,OUTPUT); digitalWrite(STEP,LOW);
 pinMode(DIR,OUTPUT); digitalWrite(DIR,LOW);
 pinMode(BUTTON,INPUT_PULLUP); pinMode(LEFT,INPUT_PULLUP); pinMode(RIGHT,INPUT_PULLUP);
 pinMode(A0,INPUT); pinMode(A1,INPUT);
 // Joystick centrado durante el arranque; una calibración extrema no permite mover.
 long sum=0; for(uint8_t i=0;i<32;i++){sum+=analogRead(A0); delay(2);}
 center=sum/32;
 armed=(center>350 && center<674);
 updateMs=millis();
}
void loop(){
 const uint32_t now=millis();
 if(firing && uint32_t(now-shotStart)>=PULSE_MS){digitalWrite(SOL,LOW); firing=false;}
 bool raw=digitalRead(BUTTON);
 if(raw!=rawPrev){rawPrev=raw; buttonChange=now;}
 if(uint32_t(now-buttonChange)>=25 && raw!=stable){
  stable=raw;
  if(!stable && !firing && (!everShot || uint32_t(now-lastShot)>=COOLDOWN_MS)){
   digitalWrite(SOL,HIGH); firing=true; shotStart=lastShot=now; everShot=true;
  }
 }
 if(uint32_t(now-sampleMs)>=5){sampleMs=now; axis=analogRead(A0); (void)analogRead(A1);}
 // NC cerrado = LOW. Pulsado o cable roto = HIGH. Parada sin rampa hacia ese extremo.
 bool left=digitalRead(LEFT)==HIGH, right=digitalRead(RIGHT)==HIGH;
 if((speed<0 && left)||(speed>0 && right))speed=0;
 int delta=axis-center;
 float target=0;
 if(armed && abs(delta)>60){
  target=(delta>0?1.0f:-1.0f)*min(1.0f,(abs(delta)-60)/400.0f)*MAX_SPEED;
 }
 if((target<0 && left)||(target>0 && right))target=0;
 if(uint32_t(now-updateMs)>=5){
  float dt=min(uint32_t(now-updateMs),uint32_t(20))/1000.0f; updateMs=now;
  float change=ACCEL*dt;
  if(speed<target)speed=min(speed+change,target);
  else if(speed>target)speed=max(speed-change,target);
 }
 if(abs(speed)<1){digitalWrite(ENABLE,HIGH);lastStep=micros();return;}
 if((speed<0 && left)||(speed>0 && right)){speed=0;digitalWrite(ENABLE,HIGH);return;}
 digitalWrite(ENABLE,LOW);
 uint32_t us=micros(), interval=uint32_t(1000000.0f/abs(speed));
 if(uint32_t(us-lastStep)>=interval){
  digitalWrite(DIR,speed>0?RIGHT_LEVEL:!RIGHT_LEVEL);
  delayMicroseconds(3);
  // Releer límites justo antes del pulso.
  if(digitalRead(speed>0?RIGHT:LEFT)==LOW){
   digitalWrite(STEP,HIGH);delayMicroseconds(3);digitalWrite(STEP,LOW);
  }
  lastStep=us;
 }
}

// Pines revisados: STEP D2, DIR D3, EN D4; VDD 5 V separado de VMOT.

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace, diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik