Tourelle Nerf Bluetooth
Composants et fournitures
| | × | 1 | |
| | × | 1 | |
| Convertisseur buck LM2596 | | × | 1 | |
| | × | 3 | |
| moteurs à courant continu type 130 | | × | 2 | |
| Diode de redressement FR207 | | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| Vis autotaraudeuses M2x10 | | × | 30 | |
| | × | 4 | |
| | × | 15 | |
| tige métallique de 1,5 mm | | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| Alimentation 9V (2,5 ampères minimum) | | × | 1 | |
Applications et services en ligne
À propos de ce projet
Merci d'avoir vérifié mon projet de tourelle Nerf contrôlée par Bluetooth. Je ne pense pas qu'il y ait trop d'explications à faire ici, il s'agit d'une tourelle Nerf contrôlée via Bluetooth depuis un appareil Android ou un PC.
....................https://www.littlefrenchkev.com/bluetooth-nerf-turret.................. .....
COMMENT ÇA MARCHE ?
Rien de super complexe. Le mouvement d'inclinaison et de panoramique est géré par 2 servos entraînés par un Arduino Nano.
Les fléchettes sont tirées à l'aide de 2 rouleaux entraînés par 2 petits moteurs à courant continu. Un servo pousse les fléchettes dans les rouleaux lorsque l'ordre de tir est envoyé. Le chargeur peut contenir 7 fléchettes.
Comme mentionné ci-dessus, il est contrôlé via Bluetooth à partir d'un appareil Android ou d'un PC.
COMMENT LE CONSTRUIRE ?
ASSEMBLAGE :
Le trépied et le magazine sont disponibles en deux versions différentes. L'un conçu pour les servos MG-90s et l'autre pour les servos MG996r. Les servos MG996r peuvent être gourmands en énergie. Assurez-vous que votre alimentation sera à la hauteur si vous décidez de les utiliser.
Trépied :
Revue :
CABLAGE :
LOGICIEL ET TEST !!!
QUELQUES PHOTOS SUPPLÉMENTAIRES PARCE QUE POURQUOI PAS !!!
Code
Code ArduinoArduino
code à télécharger sur l'arduino. Le code reste le même que vous choisissiez de contrôler la tourelle via l'application Android ou un PC.#include //-----Déclarez les servos et les variablesServo recoil_servo;Servo pan_servo;Servo tilt_servo;const octet pan_limit_1 =0;octet const pan_limit_2 =180;octet const tilt_limit_1 =65;octet const tilt_limit_2 =180;octet const recoil_rest =180; // Angle du servo au repos octet recoil_pushed =125; // Angle que le servo doit atteindre pour pousser la fléchette //-----Variables liées à la gestion des données sériebyte 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 liée à la synchronisation du moteur et à l'allumagebool is_firing =false;bool can_fire =false;bool recoiling =false;unsigned long fire_start_time =0;unsigned long fire_current_time =0;const long fire_time =150;unsigned long recoil_start_time =0;unsigned long recoil_current_time =0;const long recoil_time =2 * fire_time;const byte motor_pin =12;boolean motors_ON =false;//8===========================Dvoid setup(){ //-----définir le mode de broche du moteur pinMode(motor_pin, OUTPUT); digitalWrite(motor_pin, LOW); //-----attache le servo aux broches recoil_servo.attach(9) ; pan_servo.attach(10) ; tilt_servo.attach(11); //-----séquence de démarrage recoil_servo.write(recoil_rest); pan_servo.write(90); retard(1000); tilt_servo.write(105); Serial.begin(9600); // commencer la communication série}//8===========================Dvoid loop(){ getDataFromPC(); set_motor(); if (data_received) { move_servo(); set_recoil(); set_motor(); } fire();}//8===========================Dvoid getDataFromPC() { // structure attendue des données [octet de début , quantité de panoramique, quantité d'inclinaison, moteur allumé, bouton de tir enfoncé, octet de fin] //octet de démarrage =255 //quantité de panoramique =octet entre 0 et 253 //quantité d'inclinaison =octet entre 0 et 253 //moteur allumé =0 pour off - 1 on //bouton de tir enfoncé =0 pour non enfoncé - 1 pour enfoncé //end byte =254 if (Serial.available()) { // Si les données sont disponibles en série byte_from_app =Serial.read(); //lire le prochain caractère disponible if (byte_from_app ==255) { // rechercher l'octet de début, s'il est trouvé :bytesRecvd =0 ; //réinitialiser l'octet reçu à 0 (pour commencer à remplir inputBuffer depuis le début) data_received =false; } else if (byte_from_app ==254) { // recherche l'octet de fin, s'il est trouvé :data_received =true ; // définit data_received sur true pour que les données puissent être utilisées } else { // ajoute les octets reçus au tampon inputBuffer[bytesRecvd] =byte_from_app; //ajoute un caractère au tampon d'entrée bytesRecvd++ ; // incrémente l'octet reçu (cela agit comme un index) if (bytesRecvd ==buffSize) { // juste une sécurité au cas où le inputBuffer se remplit (ne devrait pas arriver) bytesRecvd =buffSize - 1; // if bytesReceived> buffer size set bytesReceived plus petit que la taille du buffer } } }}//8===========================Dvoid move_servo( ) { octet pan_servo_position =map(inputBuffer[0], 0, 253, pan_limit_2, pan_limit_1);//convertir la valeur du tampon d'entrée en valeur de position du servo pan_servo.write(pan_servo_position); //définir l'octet de position du servo panoramique tilt_servo_position =map(inputBuffer[1], 0 , 253, tilt_limit_2, tilt_limit_1); //convertir la valeur du tampon d'entrée en valeur de position du servo tilt_servo.write(tilt_servo_position); //définir la position du servo panoramique}//8===========================Dvoid set_recoil() { if (inputBuffer[3] ==1) { //si le bouton de tir est enfoncé if (!is_firing &&!recoiling) { //et pas déjà tirer ou reculer can_fire =true; //set can fire to true (voir effet dans void fire()) } } else { // si le bouton fire n'est pas enfoncé can_fire =false; //set can fire to false (voir effet dans void fire()) }}//8===========================Dvoid set_motor () { //-----démarrer et arrêter les moteurs à l'aide d'un transistor MOSFET. if (inputBuffer[2] ==1) { //si l'écran a touché digitalWrite(motor_pin, HIGH); //allumer le moteur motors_ON =true; } else { // si l'écran n'est pas touché digitalWrite(motor_pin, LOW); //éteindre le moteur motors_ON =false; }}//8===========================Dvoid fire() { //si l'octet du moteur est activé, allumez le moteur et vérifiez heure à laquelle il a été allumé if (can_fire &&!is_firing &&motors_ON) { //if (can_fire &&!is_firing) { fire_start_time =millis(); recoil_start_time =millis(); is_firing =vrai; } fire_current_time =millis(); recoil_current_time =millis(); if (is_firing &&fire_current_time - fire_start_time recoil_time) { is_firing =false; }}
fichiers python
L'exécutable et l'application Android sont disponibles ici :https://www.littlefrenchkev.com/bluetooth-nerf-turrethttps://github.com/LittleFrenchKev/Bluetooth_Nerf_turret Schémas
Voici le schéma de câblage principal.
Le câblage est divisé en petites sections reliées entre elles à l'aide de connecteurs dupont. C'est pour la facilité d'assemblage. Voici le câblage Bluetooth HC-05.
Ce morceau de câblage comprend un diviseur de tension pour permettre au 5V sortant de l'arduino d'être réduit à environ 3,3V pour la broche du récepteur HC-05.