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

Virtual Arduino Tennis

Componentes e suprimentos

Arduino Nano R3
× 2
SparkFun 9DoF Sensor Stick
× 1
Fios de jumpers (genérico)
× 1
NeoPixel strip
× 1
Módulo Bluetooth HC-05
× 1
Bateria de 9 V (genérica)
× 1

Ferramentas e máquinas necessárias

Ferro de soldar (genérico)

Aplicativos e serviços online

Arduino IDE

Sobre este projeto


Este projeto tem 3 partes:o tabuleiro / display do jogo, o controlador e o roteador mestre (script Python).





Parte 1 - A tela


A tela é uma matriz de neopixel 15x10 que roda em um Arduino Nano. Ele lida com a lógica do jogo e a entrada do script Python em execução em um computador host. Ele exibe uma bola que cresce e se move mais para baixo na matriz - dando uma ilusão de profundidade e a bola vindo em sua direção. Se for detectado que a bola foi rebatida, a bola será redesenhada indo 'para longe' de você.





Pontos


A direção da bola (esquerda ou direita) muda a cada rebatida. Se você errar a bola, o COM ganha um ponto, mas se o COM erra (uma chance de 25%), você ganha o ponto. Este design de jogo é semelhante à versão Wii Sports do tênis. Os pontos são exibidos sempre que o COM marca contra o jogador.





Pontuação alta


Há uma pontuação alta em execução que é armazenada em um EEPROM I2C, no endereço 0x04. Ele mantém um byte que contém a pontuação mais alta. Se você tiver uma pontuação mais alta do que a pontuação anterior anterior, o endereço será sobrescrito. Se o COM obtiver uma pontuação de 10, é o fim do jogo ... Se isso é confuso, fiz um gráfico lógico:





Faça a matriz


Fazer a matriz levará algum tempo, então siga o guia que fiz aqui.





Parte 2 - O controlador


O controlador é outro Arduino Nano que tem um stick 9DoF (apenas 3v3!) E um módulo HC-05 BLE conectado a ele. Se a aceleração do eixo x ou y for maior do que um limite especificado, ele envia um '1' via serial para o PC host, onde é retransmitido para o display. O Nano faz uma leitura do acelerômetro xey em um intervalo definido, onde verifica se os valores estão acima ou abaixo de 1,5 gramas. Para acessar o stick I2C 9 DoF, você deve instalar a biblioteca Sparkfun, que pode ser baixada aqui. Também há um tutorial sobre como conectar o sensor e executar programas básicos com ele aqui.

Para construir a raquete, usei uma caixa e recortei o formato de uma raquete em um pedaço de papelão. A partir daí foi fácil - basta colocar um pedaço de papel branco sobre o recorte de papelão e desenhar um desenho sobre o papel. Usei uma bateria de 9v para alimentar a configuração, apenas certifique-se de executar a bateria através do pino Vin do Nano, ou então será um 9v não regulado! Aqui está uma foto dos internos dentro da raquete:





Comunique-se via Bluetooth


Agora você deve estar se perguntando, o que controla essa operação complexa? Como a raquete se comunica com a tela? Aqui está um segredo:eles não se falam! Existe um script Python simples que usa a porta COM Bluetooth de entrada e a porta COM de matriz para retransmitir informações entre elas. Também ajuda a sincronizar os dois sistemas, pois ambos são redefinidos quando as portas seriais são inicializadas. A raquete envia um '1' para o script Python via Bluetooth e, em seguida, o script Python envia um '1' para o matrix. Há um debounce de 1 segundo para que as portas seriais não tenham seus buffers sobrecarregados (eles têm apenas buffers de 32 bits).





A raquete


Clique nas fotos para ver como construí a raquete:

Divirta-se com seu novo jogo de tênis!

Um vídeo de tênis sendo jogado:


Código

  • Código de matriz
  • Código da raquete
  • Código Python
Código de matriz C / C ++
Vai no Arduino anexado à matriz.
 #include  #include  #include  #include  #include  #define PIN 6 // Pino de dados para a matriz # define EEPROM_ADR 0x50 // O endereço I2C da EEPROM # define HS_ADR 0x02 // O endereço do byte de pontuação máxima na EEPROM # define NOTE_C1 33 # define SPKR_PIN 3Adafruit_NeoMatrix matrix =Adafruit_NeoMatrix (15, 10, PIN, NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG, NEO_GRB + NEO_KHZ800); int ball_x =7; // Coordenar X da bola ball_y =2; // Raio da coordenação Y da bola =1; // Raio da bola r_incr =1; // Quanto aumentar o raio bybool isSwung =false; // O raquet swungint ball_x_dir =1; // Direção do X da bola ball_y_dir =1; // Y directionbool da bola isDirRight =true; int score =0; // A pontuação do gameint atual COM_score =0; int highscore =0; // A pontuação mais alta de todos os gamesint framerate =50; // Quantos ms entre cada frameint serial_data; String score_string =""; uint16_t colors [] ={matrix.Color (255,0,0), matrix.Color (0,255,0), matrix.Color (150,200,0) }; melodia int [] ={0}; tempo int [] ={0}; lastFrame longo sem sinal estático =0; configuração void () {Serial.begin (9600); matrix.begin (); matrix.fillScreen (0); matrix.setTextColor (cores [1]); randomSeed (analogRead (A2)); display_scores (); highscore =read_HS (); Serial.println (highscore, DEC); matrix.setCursor (0,1); matrix.print ("HS:"); matrix.show (); atraso (1000); matrix.fillScreen (0); matrix.setCursor (0,1); matrix.print (highscore, DEC); matrix.show (); atraso (1000); score_string ="";} void loop () {if ((lastFrame + framerate)  =5 &&ball_y <7 &&isSwung) {if (isDirRight) {ball_x_dir =-1; ball_y_dir =-1; } else if (! isDirRight) {ball_x_dir =1; ball_y_dir =-1; } r_incr =-1; } else if (ball_y> =8) {COM_score + =1; end_round (); } else if (ball_y <=2) {isDirRight =! isDirRight; int randNum =aleatório (4); Serial.println (randNum); if (randNum ==2) {// 25% de chance de COM faltar pontuação + =1; if (pontuação> pontuação máxima) {write_HS (); } end_round; } else {if (isDirRight) {ball_x_dir =1; ball_y_dir =1; } else if (! isDirRight) {ball_x_dir =-1; ball_y_dir =1; } r_incr =1; }} ball_x + =ball_x_dir; ball_y + =ball_y_dir; raio + =r_incr; matrix.fillScreen (0); matrix.fillCircle (ball_x, ball_y, radius, colors [2]); matrix.show ();} void end_round () {if (COM_score> =10) {end_game (); } isDirRight =true; r_incr =1; ball_x_dir =1; ball_y_dir =1; ball_x =7; bola_y =2; raio =1; display_scores (); matrix.fillScreen (0); matrix.fillCircle (ball_x, ball_y, radius, colors [2]); matrix.show (); } void end_game () {matrix.fillScreen (0); matrix.setCursor (0,1); matrix.setTextColor (colors [0]); matrix.drawLine (3,0,12,9, cores [0]); matrix.drawLine (11,0,2,9, cores [0]); matrix.show (); atraso (500); while (1) {}} void display_scores () {matrix.fillScreen (0); matrix.setTextColor (cores [1]); matrix.setCursor (0,1); score_string =String (score) + "-" + String (COM_score); scrollText (score_string); matrix.fillScreen (0); atraso (2000); matrix.show ();} void scrollText (String text) {int pass =0; int x =matriz.largura (); para (int i =0; i <24; i ++) {matrix.fillScreen (0); matrix.setCursor (x, 2); matrix.print (texto); x - =1; matrix.show (); atraso (150); }} void write_HS () {EEPROM.write (0x04, int (pontuação));} int read_HS () {byte HS =EEPROM.read (0x04); // Ler a partir do endereço 4 return HS;} 
Código da raquete C / C ++
 #include  #include  #include  LSM9DS1 imu; #define LSM9DS1_M 0x1E // Seria 0x1C se SDO_M fosse LOW # definir LSM9DS1_AG 0x6B // Seria 0x6A se SDO_AG é LOW # define PRINT_SPEED 10 // 10 ms entre checksstatic unsigned long lastPrint =0; // Acompanhe a impressão timefloat accelx =0; float accely =0; void setup () {// coloque seu código de configuração aqui, para ser executado uma vez:Serial.begin (9600); imu.settings.device.commInterface =IMU_MODE_I2C; imu.settings.device.mAddress =LSM9DS1_M; imu.settings.device.agAddress =LSM9DS1_AG; if (! imu.begin ()) {// falhou enquanto (1); }} void loop () {if ((lastPrint + PRINT_SPEED)  =1,5) {Serial.print (1); atraso (600); } else if (accely <=-1,5 || accely> =1,5) {Serial.print (1); atraso (600);}} 
Código Python Python
 import serialimport timematrix_port ="COM3" raquet_port ="COM9" matrix =serial.Serial (matrix_port, 9600) racquet =serial.Serial (raquet_port, 9600) time.sleep (10) while 1:data =racquet.read ( ) imprimir dados se dados =="1":imprimir "hit" matrix.write ("1") time.sleep (1) time.sleep (.05) 

Esquemas


Processo de manufatura

  1. Detector de linguagem TinyML baseado em Edge Impulse e Arduino
  2. Jogo Arduino Gyroscope com MPU-6050
  3. Dados digitais Arduino
  4. Homem de Ferro
  5. Encontre-me
  6. Controle do umidificador Arduino
  7. Sonar usando arduino e exibição no IDE de processamento
  8. MobBob:DIY Arduino Robot Controlado por Smartphone Android
  9. Arduino Audio Reactive Desk Light
  10. NeoMatrix Arduino Pong