CAÑÓN DE ARTILLERÍA-GRUPO4- VICÁLVARO
Alberto Ortega Cabrera, Miguel González Rodríguez, Pablo Rodríguez González.

1.Introducción
Para este proyecto, hemos diseñado e implementado un sistema de disparo automatizado basado en Arduino para controlar una pistola “Nerf” mediante el uso de Bluetooth. El dispositivo nos permite desplazar la “Nerf” en el eje vertical y disparar a distancia a través de una aplicación móvil desarrollada en Kotlin. Para controlar tanto el disparo como el movimiento hacemos uso de dos servomotores, uno situado cerca del gatillo y otro en una zona intermedia para inclinar correctamente el cañón.
2. Arquitectura del Sistema
- Arduino UNO: Controlador central que recibe comandos vía Bluetooth y genera pulsos PWM para los servos.
- Módulo HC-05: El módulo nos permite la comunicación de nuestro sistema con la aplicación Android lo que nos dará un control cómodo y sencillo del cañón.
- Servomotores:
- Servo 1 (tiltServo) en pin 5: mueve el cañón arriba/abajo.
- Servo 2 (triggerServo) en pin 6: acciona el gatillo.
- Nerf: Es la base de nuestro cañón, y se trata del componente que tendrá las balas para su posterior disparo.
- Aplicación Android (Kotlin): aplicación para Android creada por nosotros, la cuál nos permite ejecutar el movimiento y disparo del cañón mediante una interfaz sencilla de 3 botones: UP, DOWN y FIRE.


2.1 Montaje(Estructura):
En primer lugar, cortamos el corcho en forma vertical para establecer el lugar en el que iría pegada la «Nerf».
En segundo lugar, pegamos ese trozo de corcho a la base y el servo de movimiento junto a la «Nerf» a la pieza vertical.
Por último, dejamos secar el pegamento y ejecutamos las diferentes pruebas de movimiento y disparo.



3. Implementación
3.1 Hardware:
- Montaje de la Nerf sobre una base estable de corcho para no tener que sujetarla con la mano, para ello utilizando pegamento termofusible.
- Fijación del servo de inclinación en una posición intermedia para controlar el ángulo de movimiento de forma correcta.
- Servo de disparo pegado cerca del gatillo para que al ejecutar la opción de disparar haga contacto con él.
- Servos conectados a los pines 5 y 6 del Arduino respectivamente.
- Conexión del módulo HC-05 a pines RX/TX (SoftwareSerial en 0,1).
- Alimentación por USB desde nuestro ordenador.
3.2 Software Arduino
- Uso de la librería Servo para generar PWM.
- SoftwareSerial a 9600 baudios para HC-05.
- Lectura de los diferentes comandos ‘U’,’D’,’F’.
- Funciones: handleCommand() y shoot().
3.3 Aplicación Móvil (Kotlin)
- Interfaz con tres botones (UP, DOWN, FIRE).
- Solicitud de permisos Bluetooth para dispositivos Android 12 o superior.
- Búsqueda y conexión a HC-05.
- Envío de caracteres ASCII correspondientes.
4. Pasos Realizados para el diseño e implementación
- Reunión inicial y definición de requisitos: en esta primera reunión, debatimos sobre la idea que finalmente queríamos implementar y los materiales que necesitaríamos para ello. Por lo tanto, llegamos a una conclusión y realizamos la compra de los materiales.
- Diseño de la base y sujeción: pusimos varias opciones para la estructura del propio cañón y como pegaríamos la “nerf” a la misma. Finalmente, nos decantamos por el corcho y el pegamento termofusible, ya que eran materiales fiables para la sujeción.
- Cableado y pruebas de los servomotores: realizamos una serie de pruebas de funcionamiento de los servomotores, además de decidir cuales serían sus posiciones óptimas para el funcionamiento del cañón. Tras comprobar que los servos funcionaban correctamente los pegamos en sus respectivas posiciones.
- Comunicación Bluetooth: buscamos documentación de como conectar correctamente el módulo a la placa y del voltaje necesario. Una vez informados, implementamos un divisor de tensión con dos resistencias (2,2 k y 1k) ya que el voltaje de los pines TX y RX es 3,3V en vez de 5V. Por último, desarrollamos el código correspondiente.
- Desarrollo de la app y pruebas: esta fue la parte más complicada ya que no habíamos desarrollado nunca una app de móvil, sin embargo, gracias a que el lenguaje es bastante parecido a Java pudimos resolver las dificultades encontradas.
- Integración y pruebas finales: una vez montado todo el proyecto, comprobamos el correcto funcionamiento de cada uno de los componentes mediante una serie de pruebas. Finalmente, presentamos el proyecto presencialmente en clase.
5. Reparto de Tareas
Todos los miembros del grupo trabajamos de forma equitativa, mediante reuniones presenciales. No hay una tarea específica para cada miembro, ya que según el día cada uno trabajaba con una parte diferente pero siempre con la ayuda del resto si así era necesario.
6. Materiales y Costes
Elemento | Precio(€) |
Pistola “Nerf” | 7.99 |
Servomotores(x2) | 10.99 |
Módulo bluetooth HC-05 | 10.50 |
Protoboard, cables y resistencias | Proporcionado por ETSII |
Placa Arduino UNO | Proporcionado por ETSII |
Pistola pegamento termofusible. | 0.00 |
Total aproximado | 29.48 |
7. Problemas y Soluciones
- Giro 360º: en un primer momento, nuestra idea fue implementar un movimiento para nuestro cañón de 360º. Para ello, queríamos hacer uso de un step motor. Sin embargo, el peso y volumen de la estructura era demasiado para el step motor. Para solucionar esto, nos centramos en el correcto funcionamiento del movimiento vertical y descartamos ese movimiento 360.
- Desprendimiento del servo de disparo: tras montar el sistema completo realizamos una gran cantidad de pruebas de disparo, es por ello que el servomotor de disparo se despegó levemente del gatillo evitando el contacto con el mismo. Para solucionarlo, al disparar ejercemos fuerza en el servo para acercarlo al gatillo, de esta forma el disparo se ejecuta correctamente.
- Uso de Nerf de gama baja: debido a nuestro presupuesto, hicimos uso de una nerf de gama baja la cual no cuenta con elementos electrónicos. Por ello, no pudimos automatizar electrónicamente algunas de las funcionalidades como la recarga del cañón.
8. Casos de Uso
- Mover hacia arriba (UP): Usuario pulsa «UP» en la app → app envía ‘U’ → Arduino reduce el ángulo en 5° (hasta 30°) → Nerf se inclina hacia arriba.
- Mover hacia abajo (DOWN): Usuario pulsa «DOWN» → envía ‘D’ → Arduino aumenta el ángulo en 5° (hasta 150°) → Nerf se inclina hacia abajo.
- Disparar (FIRE): Usuario pulsa «FIRE» → envía ‘F’ → Arduino ejecuta shoot() → triggerServo impulsa el gatillo (ángulo 120°) → Nerf dispara.
9. Código Fuente
9.1 Código Arduino
#include <Servo.h>
#include <SoftwareSerial.h>
// Bluetooth on pins 10 (RX) and 11 (TX)
SoftwareSerial BTSerial(0, 1);
// Servo objects
Servo tiltServo; // For up/down movement
Servo triggerServo; // For firing
// Pins for the servos
const int tiltPin = 5;
const int triggerPin = 6;
// Variables to track tilt position
int tiltAngle = 90; // Start at middle (can adjust)
const int tiltStep = 5; // How much to move per command
const int tiltMin = 30; // Minimum tilt angle
const int tiltMax = 150; // Maximum tilt angle
void setup() {
Serial.begin(9600);
BTSerial.begin(9600);
tiltServo.attach(tiltPin);
triggerServo.attach(triggerPin);
tiltServo.write(tiltAngle); // Initialize tilt to middle position
triggerServo.write(90); // Initialize trigger servo to 0 (resting)
Serial.println("Gun Controller Ready!");
}
void loop() {
if (BTSerial.available()) {
char command = BTSerial.read();
Serial.print("Received Command: ");
Serial.println(command);
handleCommand(command);
}
}
void handleCommand(char cmd) {
switch (cmd) {
case 'U': // Tilt Up
tiltAngle = constrain(tiltAngle - tiltStep, tiltMin, tiltMax);
tiltServo.write(tiltAngle);
Serial.print("Tilted Up. Current angle: ");
Serial.println(tiltAngle);
break;
case 'D': // Tilt Down
tiltAngle = constrain(tiltAngle + tiltStep, tiltMin, tiltMax);
tiltServo.write(tiltAngle);
Serial.print("Tilted Down. Current angle: ");
Serial.println(tiltAngle);
break;
case 'F': // Fire
shoot();
break;
default:
Serial.println("Unknown Command");
break;
}
}
void shoot() {
Serial.println("Firing!");
// Customize these angles if needed
triggerServo.write(120); // Pull trigger
delay(500); // Hold for a bit
triggerServo.write(90); // Release trigger
delay(500);
}
9.2 Aplicación Android (Kotlin)
package com.example.guncontroller
import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.annotation.RequiresPermission
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import java.io.IOException
import java.util.*
class MainActivity : AppCompatActivity() {
private lateinit var bluetoothAdapter: BluetoothAdapter
private var bluetoothSocket: BluetoothSocket? = null
// HC-05 UUID for serial communication
private val HC05_UUID: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
private val HC05_NAME = "HC-05"
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val btnUp: Button = findViewById(R.id.btnUp)
val btnDown: Button = findViewById(R.id.btnDown)
val btnFire: Button = findViewById(R.id.btnFire)
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
if (bluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth not supported!", Toast.LENGTH_LONG).show()
finish()
return
}
// Permissions for Bluetooth (Android 12+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.BLUETOOTH_SCAN
),
1
)
}
connectToHC05()
btnUp.setOnClickListener {
sendCommand("U")
}
btnDown.setOnClickListener {
sendCommand("D")
}
btnFire.setOnClickListener {
sendCommand("F")
}
}
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
private fun connectToHC05() {
val pairedDevices: Set<BluetoothDevice>? = bluetoothAdapter.bondedDevices
pairedDevices?.forEach { device ->
if (device.name == HC05_NAME) {
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(HC05_UUID)
bluetoothSocket?.connect()
Toast.makeText(this, "Connected to HC-05", Toast.LENGTH_SHORT).show()
} catch (e: IOException) {
Toast.makeText(this, "Connection failed", Toast.LENGTH_SHORT).show()
e.printStackTrace()
}
}
}
}
private fun sendCommand(command: String) {
try {
bluetoothSocket?.outputStream?.write(command.toByteArray())
Toast.makeText(this, "Sent: $command", Toast.LENGTH_SHORT).show()
} catch (e: IOException) {
Toast.makeText(this, "Failed to send command", Toast.LENGTH_SHORT).show()
e.printStackTrace()
}
}
override fun onDestroy() {
super.onDestroy()
try {
bluetoothSocket?.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
10. Conclusiones
Este proyecto nos ha permitido aplicar algunas de las cosas aprendidas en clase, además de descubrir otras como la creación de apps móviles. Por lo tanto, se podría decir que hemos cumplido con nuestro objetivo de aprendizaje y estamos satisfechos con nuestro resultado final.
11. Vídeo Explicativo