Acerca de este proyecto
Gracias por comprobar mi proyecto de torreta Nerf controlado por Bluetooth. No creo que haya mucho que explicar aquí, esta es una torreta Nerf controlada a través de Bluetooth, ya sea desde un dispositivo Android o una PC.
.................... https://www.littlefrenchkev.com/bluetooth-nerf-turret ............... .....
¿CÓMO FUNCIONA?
Nada super complejo. El movimiento de inclinación y panorámica es manejado por 2 servos impulsados por un Arduino Nano.
Los dardos se disparan con 2 rodillos accionados por 2 pequeños motores de CC. Un servo empuja los dardos hacia los rodillos cuando se envía la orden de disparar. El cargador tiene capacidad para 7 dardos.
Como se mencionó anteriormente, se controla a través de Bluetooth desde un dispositivo Android o una PC.
¿CÓMO CONSTRUIRLO?
MONTAJE:
El trípode y la revista vienen en dos versiones diferentes. Uno diseñado para servos MG-90s y el otro para servos MG996r. Los servos MG996r pueden consumir mucha energía. Asegúrese de que su fuente de alimentación esté a la altura del trabajo si decide usarlos.
Trípode:
Revista:
CABLEADO:
SOFTWARE Y PRUEBA !!!
ALGUNAS FOTOS ADICIONALES PORQUE NO !!!
Código
Código Arduino Arduino
código para subir al arduino. El código sigue siendo el mismo si elige controlar la torreta a través de la aplicación de Android o una PC. #include // ----- Declarar servos y variables Servo recoil_servo; Servo pan_servo; Servo tilt_servo; const byte pan_limit_1 =0; byte constante pan_limit_2 =180; byte constante tilt_limit_1 =65; byte constante tilt_limit_2 =180; byte constante retroceso_resto =180; // Ángulo del servo cuando está en reposo byte recoil_pushed =125; // Ángulo que debe alcanzar el servo para empujar el dardo // ----- Variables relacionadas con el manejo de datos en serie byte byte_from_app; const byte buffSize =30; byte inputBuffer [buffSize]; const byte startMarker =255; const byte endMarker =254; byte bytesRecvd =0; boolean data_received =false; // ----- Variable relacionada con la sincronización del motor y el disparo bool is_firing =false; bool can_fire =false; bool recoiling =false; unsigned long firing_start_time =0; unsigned long firing_current_time =0; const long firing_time =150; unsigned long recoil_start_time =0; unsigned long recoil_current_time =0; const long recoil_time =2 * firing_time; const byte motor_pin =12; boolean motors_ON =false; // 8 ===========================Dvoid setup () {// ----- define el modo pin del motor pinMode (motor_pin, OUTPUT); digitalWrite (motor_pin, BAJO); // ----- adjunta el servo a los pines recoil_servo.attach (9); pan_servo.attach (10); tilt_servo.attach (11); // ----- secuencia de inicio recoil_servo.write (recoil_rest); pan_servo.write (90); retraso (1000); tilt_servo.write (105); Serial.begin (9600); // iniciar la comunicación en serie} // 8 ===========================Dvoid loop () {getDataFromPC (); set_motor (); if (data_received) {move_servo (); set_recoil (); set_motor (); } fire ();} // 8 ===========================Dvoid getDataFromPC () {// estructura esperada de datos [start byte , cantidad de panorámica, cantidad de inclinación, motor encendido, botón de disparo presionado, byte final] // byte de inicio =255 // cantidad de panorámica =byte entre 0 y 253 // cantidad de inclinación =byte entre 0 y 253 // motor encendido =0 para apagado - 1 encendido // botón de disparo presionado =0 para no presionado - 1 para presionado // byte final =254 if (Serial.available ()) {// Si los datos están disponibles en serial byte_from_app =Serial.read (); // lee el siguiente carácter disponible if (byte_from_app ==255) {// busca el byte de inicio, si lo encuentra:bytesRecvd =0; // restablece el byte recibido a 0 (para comenzar a completar inputBuffer desde el inicio) data_received =false; } else if (byte_from_app ==254) {// busque el byte final, si lo encuentra:data_received =true; // establece data_received en verdadero para que los datos se puedan usar} else {// agrega los bytes recibidos al búfer inputBuffer [bytesRecvd] =byte_from_app; // agrega un carácter al búfer de entrada bytesRecvd ++; // incrementa el byte recibido (esto actúa como un índice) if (bytesRecvd ==buffSize) {// solo una seguridad en caso de que inputBuffer se llene (no debería suceder) bytesRecvd =buffSize - 1; // si bytesReceived> tamaño del búfer establecido bytesReceived más pequeño que el tamaño del búfer}}}} // 8 ===========================Dvoid move_servo ( ) {byte pan_servo_position =map (inputBuffer [0], 0, 253, pan_limit_2, pan_limit_1); // convierte el valor del búfer de entrada al valor de la posición del servo pan_servo.write (pan_servo_position); // establece la posición del servo de panorámica byte tilt_servo_position =map (inputBuffer [1], 0, 253, tilt_limit_2, tilt_limit_1); // convierte el valor del búfer de entrada al valor de la posición del servo tilt_servo.write (tilt_servo_position); // establecer la posición del servo panorámico} // 8 ===========================Dvoid set_recoil () {if (inputBuffer [3] ==1) {// si se presiona el botón de disparo if (! Is_firing &&! Retrocediendo) {// y no disparando ni retrocediendo can_fire =true; // establecer can disparar a verdadero (ver efecto en void fire ())}} else {// si no se presiona el botón de disparo can_fire =false; // establecer can disparar a falso (ver efecto en void fire ())}} // 8 ===========================Dvoid set_motor () {// ----- arranca y detiene motores usando un transisitor MOSFET. if (inputBuffer [2] ==1) {// si se toca la pantalla digitalWrite (motor_pin, HIGH); // enciende el motor motors_ON =true; } else {// si la pantalla no se toca digitalWrite (motor_pin, LOW); // apaga el motor motors_ON =false; }} // 8 ===========================Dvoid fire () {// si el byte del motor está activado, encienda el motor y compruebe tiempo que ha estado encendido if (can_fire &&! is_firing &&motors_ON) {// if (can_fire &&! is_firing) {firing_start_time =millis (); recoil_start_time =millis (); is_firing =true; } hora_corriente_de_corriente =millis (); recoil_current_time =millis (); if (is_firing &&firing_current_time - firing_start_time recoil_time) {is_firing =false; }}
archivos Python
La aplicación ejecutable y de Android se puede encontrar aquí:https://www.littlefrenchkev.com/bluetooth-nerf-turrethttps://github.com/LittleFrenchKev/Bluetooth_Nerf_turret Esquemas
Aquí está el diagrama de cableado principal.
El cableado se divide en pequeñas secciones unidas entre sí mediante conectores dupont. Esto es para facilitar el montaje. Aquí está el cableado Bluetooth HC-05.
Esta pieza de cableado incluye un divisor de voltaje para permitir que los 5V que salen del arduino se reduzcan a aproximadamente 3.3V para el pin del receptor HC-05.