Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Torre Sentinela Nerf Autônoma

Componentes e suprimentos

OpenBuilds NEMA 17 Stepper Motor
× 1
DFRobot Stepper Motor with Gearbox
× 1
DFRobot Stepper Motor Driver
× 1
DFRobot Pixy 2 Cam
× 1
Arduino Mega 2560
× 1
Sensor ultrassônico - HC-SR04 (genérico)
× 1
Pistola Nerf Nitron
× 1

Ferramentas e máquinas necessárias

Impressora 3D (genérica)
Ferro de soldar (genérico)
Roteador CNC

Aplicativos e serviços online

Arduino IDE
Autodesk Fusion 360

Sobre este projeto





Idéia


Há alguns anos, vi um projeto que apresentava uma torre semiautônoma que podia disparar sozinha depois de mirada. Isso me deu a ideia de usar uma câmera Pixy 2 para obter alvos e, em seguida, apontar a arma nerf automaticamente, que poderia travar e disparar sozinha.





Os componentes


Para este projeto, a arma precisaria de olhos, então escolhi usar o Pixy 2 devido à facilidade de interface com a placa-mãe. Então precisei de um microcontrolador, então escolhi um Arduino Mega 2560 devido à quantidade de pinos que ele possui.

Uma vez que a arma precisa de dois eixos, guinada e passo, ela requer dois motores de passo. Por causa disso, a DFRobot me enviou sua placa de driver de motor DRV8825 dupla.





CAD


Comecei carregando o Fusion 360 e inserindo uma tela anexada da arma nerf. Em seguida, criei um corpo sólido a partir dessa tela. Depois que a arma foi projetada, fiz uma plataforma com alguns suportes baseados em rolamentos que permitiriam que a arma girasse da esquerda para a direita. Coloquei um motor de passo próximo à plataforma giratória para acioná-lo.

Mas a grande questão é como fazer a arma disparar para cima e para baixo. Para isso, foi necessário um sistema de acionamento linear com um ponto preso ao bloco móvel e outro ponto na parte de trás da arma. Uma haste conectaria os dois pontos, permitindo que a arma girasse ao longo de seu eixo central.





Fabricação das peças


Quase todas as peças do meu design foram feitas para serem impressas em 3D, então usei minhas duas impressoras para criá-las. Em seguida, criei a plataforma móvel usando primeiro o Fusion 360 para gerar os caminhos da ferramenta necessários para a minha fresadora CNC e, em seguida, cortei o disco de uma folha de madeira compensada.





Montagem


Depois que todas as peças foram criadas, era hora de montá-las. Comecei conectando os suportes do rolamento ao disco giratório. Em seguida, montei o conjunto de passo linear passando as hastes de alumínio de 6 mm e a haste roscada através das peças.





Por último, fixei a própria pistola nerf com uma haste de aço e dois postes feitos de extrusões de alumínio.





Programação


Agora, a parte mais difícil do projeto:a programação. Uma máquina de lançamento de projéteis é muito complexa e a matemática por trás dela pode ser confusa. Comecei escrevendo o fluxo do programa e a lógica passo a passo, detalhando o que aconteceria em cada estado da máquina. Os diferentes estados são os seguintes:
  • Aquisição de meta
  • Posicione a arma
  • Acelere os motores
  • Dispare a arma
  • Reduza os motores

Adquirir o alvo envolve primeiro configurar o Pixy para rastrear objetos rosa neon como alvos. Em seguida, a arma se move até que o alvo esteja centralizado na visão do Pixy, onde sua distância do cano da arma ao alvo é então medida. Usando esta distância, as distâncias horizontais e verticais podem ser encontradas usando algumas funções trigonométricas básicas. Meu código tem uma função chamada get_angle () que usa essas duas distâncias para calcular quanto ângulo é necessário para atingir aquele alvo.

A arma então se move para esta posição e liga os motores por meio de um MOSFET. Depois de enrolar por cinco segundos, ele move o servo motor para puxar o gatilho. O MOSFET então desliga o motor e então a arma nerf volta a procurar alvos.





Divertir-se


Coloquei um cartão rosa neon na parede para testar a precisão da arma. Funcionou bem, pois meu programa calibra e ajusta o ângulo para a distância medida. Aqui está um vídeo demonstrando o funcionamento da arma:




Código

  • Esquemático
Esquemático C / C ++
Carregar para Arduino Mega
 #include  #include  #include "BasicStepperDriver.h" #include  #include  // X é pitch, Y é pinos internos yawconst [] ={6,7,8,5,4,12}; // MX STEP, DIR, EN, MY STEP, DIR, ENconst int limit_switch =26, laser_pin =11, spool_pin =10, servo_pin =13, distance_trig =29, distance_echo =30; velocidade dupla =21,336; velocidade dupla =455,225; flutuar ângulo_atual =0,0; flutuar hip_distância; // distância da arma ao alvo em metros # define X_MID 164 # define Y_MID 150 # define DEADZONE 15 # define G 9.8 # define STP_PER_DEG_YAW 3.333 # define STP_PER_DEG_PITCH 184859 # define MICROSTEPS 32 # define RPM 120 # define MOTOR_STEPS_Y 200 # define MOTOR_STEPS_X 1036 / /17.7777 steps / degreesBasicStepperDriver pitch_stepper (MOTOR_STEPS_X, pins [1], pins [0]); BasicStepperDriver yaw_stepper (MOTOR_STEPS_X, pins [4], pins [3]); acionador de servo; Pixy2I2CTION, pixy; enum States {ACQUIRE; , FOGO, WIND_DOWN, RETURN}; estado estado =ACQUIRE; void setup () {Serial.begin (115200); init_pins (); atraso (1000); // home_pitch (); pixy.init (); Serial.println ("Pronto ...");} void loop () {switch (estado) {case ACQUIRE:activate_target (); estado =POSIÇÃO; digitalWrite (laser_pin, HIGH); pausa; case POSIÇÃO:Serial.println ("posicionamento"); position_gun (); estado =SPOOL; pausa; case SPOOL:Serial.println ("spool"); digitalWrite (spool_pin, HIGH); atraso (5000); estado =FOGO; pausa; case FIRE:fire_gun (); estado =WIND_DOWN; pausa; case WIND_DOWN:Serial.println ("winding down"); digitalWrite (spool_pin, LOW); atraso (2000); estado =RETORNO; digitalWrite (laser_pin, LOW); estado =ADQUIRIR; pausa; }} void fire_gun () {Serial.println ("Disparando arma!"); trigger.write (108); atraso (400); trigger.write (90); atraso (2000);} void position_gun () {float x, y; hip_distância =ping (); hip_distância / =100; while (! hip_distância) {hyp_distance =ping (); hip_distância / =100; } Serial.println (hip_distância); x =cos (ângulo_atual) * hip_distância; y =sin (ângulo_atual) * hip_distância; float target_angle =get_angle (x, y); target_angle / =100; Serial.println (ângulo_alvo); move_pitch (target_angle - current_angle); ângulo_atual =ângulo_alvo;} void adquirir_destino () {int x =0, y =0; passos longos_taken =0; bool lock =false; while (! lock) {pixy.ccc.getBlocks (); if (pixy.ccc.numBlocks) {x =pixy.ccc.blocks [0] .m_x; y =pixy.ccc.blocks [0] .m_y; Serial.print ("Alvo visto no local X:"); Serial.print (x); Serial.print (", Y:"); Serial.println (y); if (x <=(X_MID - DEADZONE)) {// Se for muito para a esquerda, mova a arma para a esquerda move_yaw (1); } else if (x> =(X_MID + DEADZONE)) {move_yaw (-1); } else if (y <=(Y_MID - DEADZONE)) {// muito para cima, mova a arma para cima pitch_stepper.move (33152); passos_tinhados + =33152; } else if (y> =(Y_MID + DEADZONE)) {pitch_stepper.move (33152); passos_tinhados + =33152; } else {lock =true; Serial.print ("Alvo bloqueado no local X:"); Serial.print (x); Serial.print (", Y:"); Serial.println (y); Serial.print ("Etapas realizadas:"); Serial.println (etapas_taken); }}} ângulo_atual =etapas_taken / STP_PER_DEG_PITCH; Serial.print ("Ângulo atual:"); Serial.println (ângulo_atual);} void init_pins () {pinMode (pinos [2], SAÍDA); pinMode (pinos [5], SAÍDA); pinMode (limit_switch, INPUT_PULLUP); pinMode (laser_pin, OUTPUT); pinMode (spool_pin, OUTPUT); pinMode (distance_echo, INPUT); pinMode (distance_trig, OUTPUT); digitalWrite (pinos [2], LOW); digitalWrite (pinos [5], LOW); digitalWrite (laser_pin, LOW); digitalWrite (spool_pin, LOW); trigger.attach (servo_pin); pitch_stepper.begin (RPM, MICROSTEPS); yaw_stepper.begin (5, MICROSTEPS); trigger.write (90);} void move_yaw (graus flutuantes) {yaw_stepper.move (graus * STP_PER_DEG_YAW * 32);} void move_pitch (graus flutuantes) {ângulo_atual + =graus; pitch_stepper.move (degrees * STP_PER_DEG_PITCH);} float get_angle (distância do float, altura do float) {float i =2 * height * 455,225; flutuante j =G * distância * distância; i + =j; j =9,8 * i; i =sqrt (pow (velocity_squared, 2) - j); return atan ((velocity_squared-i) / (G * distance)) * (180 / PI);} float ping () {Serial.println ("Obtendo distância ..."); longa duração; digitalWrite (distance_trig, LOW); atrasoMicrosegundos (5); digitalWrite (distance_trig, HIGH); atrasoMicrosegundos (10); digitalWrite (distance_trig, LOW); duração =pulseIn (distance_echo, HIGH); duração do retorno / 2 / 29,1; // distância em metros} void home_pitch () {Serial.println (digitalRead (limit_switch)); if (! digitalRead (limit_switch)) {// Se a chave estiver ativa pitch_stepper.rotate (720); } while (digitalRead (limit_switch)) {//Serial.println(digitalRead(limit_switch)); pitch_stepper.move (-32); } pitch_stepper.rotate (2880 * 2);} 

Peças personalizadas e gabinetes

Repositório Thingiverse
Arquivo CAD em thingiverse.com

Esquemas


Processo de manufatura

  1. Motores de passo
  2. Drivers integrados facilitam o design do motor de passo
  3. Protótipo da Raspoulette
  4. Robô Pi Simples
  5. Biblioteca de motor de passo bipolar
  6. Swiper - Auto Tinder / Bumble Swiper
  7. Robô assistente autônomo da casa
  8. A área cinzenta entre servomotores e motores de passo
  9. O que é um Motor Linear?
  10. O que é um servo motor?