Hackeando Controle de Playstation com Arduino em Controle Remoto para projetos, Modelos e Miniaturas – V08

Arduino é um Ótimo hobby, com ele você mesmo consegue construir várias coisas legais, desenvolvendo suas habilidades e criatividade, este será, com certeza, o primeiro de muitos projetos que você ainda irá desenvolver com Arduino.

Controle de Playstation com Arduino em Controle Remoto para projetos, Modelos e Miniaturas – V08. Arduino Para Modelismo – 1 de set. de 2018

Neste vídeo Arduino Para Modelismo mostra um pouco de como modificou um Controle de Playstation para fazer um controle remoto sem fio usando Arduino e o Módulo NRF24l01. Pode ser usado para carrinho, caminhão, barco e projetos em geral. Esse é um método bem simples, mais indicado para quem está começando. Existe outros métodos onde se utiliza a própria eletrônica do controle de Playstation2.

Para a montagem da Eletrônica do controle remoto foram usados os seguintes componentes:

  • 1 Controle de playStation 2
  • 1 Arduino Pro Mini 5v
  • 1 Módulo NRF24L01+
  • 1 Regulador de tenção
  • 1 Resistor de 100 Ohms
  • 1 Capacitor eletrolítico 47 uF superior a 5 volts
  • 1 Célula de Bateria de notebook ( ou 1 bateria 18650)
  • 1 Buzzer Passivo
  • Fios para as conexões e solda

Connections from PS2 PCB to Arduino Mini pins

The PS2 controller signal transmission project via radio used an Arduino Nano that read the PS2 signals and transmitted them with an nRF24l0 module, inspired by Fabio’s blog, which led to the incorporation of the battery, the charging circuit and the Arduino directly on the controller. Shepherding electrons – 

  • “Long range” modules nRF24l01+PA/LNA – which are supposed to have a range of up to 1000 meters…!
  • an Arduino Mini module, using the Atmega328 AVR at 3.3V, mainly because of its small form factor
  • a USB port
  • charging circuit for a 1S LiPo battery
  • a red LED which is controlled by the Arduino for a visual indication
  • a green LED
  • a yellow LED has been added to indicate charging status and an SPDT button on the side controls power
  • a mini piezo buzzer to provide feedback on radio status, etc.

nRF24l01 with color-coded Arduino Pro Mini pin connections

Power management and reduced space inside the controller were addressed with a very small 1S LiPo battery and a modified TP4056 charging module, as the “resting” voltage of a 1S LiPo battery is 3.7V, fully charged is 4.2V and about 3.3V at minimum load. The Arduino board is clocked at 8MHz and should be able to step up to 5.5V without any problems. The nRF24l01 module is out of specification as it is a 3.3 – 4.2 V module, and could/should have used a 3.3 V linear regulator with low voltage drop (or MCP1700-3302E).

TP4056 charging circuit with a 1S LiPo battery.  Some components were desoldered, LEDs were connected and a power switch attached.

The TP4056 module USB port was desoldered (to save space), and the IN+ and IN- were connected to VBUS (5.0V) and GND of the mini-USB port breakout module.  Further, the two charge indicator LEDs were removed and 3 mm yellow and green LEDs were connected.  Finally BAT+ and BAT- were soldered to the battery VERY CAREFULLY, ACCIDENTAL HEAT ON A LiPo BATTERY CAN CAUSE FIRES! The Vcc from the switch was connected to Vcc of the rest of the circuit – i.e. to power the Arduino, PS2 PCB and nRF24l01 radio module.

A small piezo speaker (3.3V), added to report radio packet acknowledgment status – a low, monotone tone every second when the radio fails to send, and a musical trill when a radio packet is sent successfully.

The software to run on the PS2 controller is fairly straightforward.  We’ll need a PS2 controller library from here and the Mirf radio library from here.  We setup the radio module (with ACK acknowledgements enabled), then the PS2 controller (the code is inherited directly from the PS2 library example).

Modified PS2 Controller with Arduino and NRF24L01+ in action part 1dgmark. 24 de ago. de 2017

PS2 controller + Arduino + NRF24L01+ controlling a modified toy RC car. dgmark

Gathering Materials

  • 1 x Wired PS2 controller (clone)
  • 1 x Arduino nano
  • 1 x NRF24L01+PA+LNA
  • 1 x Socket Adapter Module Board for NRF24L01+ (or you can try to directly power it using the 3.3v of the arduino but put a capacitor to make the voltage smoother)
  • 2 x 16340 Li-ion battery
  • 1 x USB Lithium Battery Charger Module Board
  • 1 x toggle switch
  • 1 x small dc motor (optional)
  • 1 x L293D motor driver (optional, only if you add dc motor for vibration)

PS2 controller code:

DATA HOSTED WITH ♥ BY PASTEBIN.COM – DOWNLOAD RAW – SEE ORIGINAL

  1. #include <PS2X_lib.h>
  2. #include <SPI.h>
  3. #include <Mirf.h>
  4. #include <nRF24L01.h>
  5. #include <MirfHardwareSpiDriver.h>
  6. #define PS2_DAT        4
  7. #define PS2_CMD        3
  8. #define PS2_SEL        2
  9. #define PS2_CLK        5
  10. #define MY_LED 6
  11. #define SPEAKER 9
  12. PS2X ps2x; // create PS2 Controller Class  
  13. uint8_t tx_address[5] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7};
  14. uint8_t rx_address[5] = {0xD7, 0xD7, 0xD7, 0xD7, 0xD7};
  15. #define toggle_pin(port, pin) port^=(1<<pin)
  16. struct radio_packet
  17. {
  18.  uint8_t buttons1;
  19.  uint8_t buttons2;
  20.  uint8_t leftX;
  21.  uint8_t leftY;
  22.  uint8_t rightX;
  23.  uint8_t rightY;
  24. }radioData;
  25. enum connection_state {WAITING=0, POOR=1, GOOD=2};
  26. void playMelody(void)
  27. {
  28.  for (uint8_t i=10;i>0;i–)
  29.  {
  30.  // pin, freq (Hz), duration (ms)
  31.     tone(SPEAKER, 100+(uint16_t)i*50,100);
  32.     delay(100);
  33.  }
  34. }
  35. void ConnectedBeep(void) // This function has the potential to block radio calls if we’re moving between poor and good
  36. {  // threshold every second… Can this be made non-blocking?
  37.  for (uint8_t i=0;i<10;i++)
  38.  {
  39.     tone(SPEAKER, 100+(uint16_t)i*50,50);
  40.     delay(50);
  41.  }
  42. }
  43. void WaitingBeep(void)
  44. {
  45.   tone(SPEAKER, 100, 200); 
  46. }
  47. void LowSignalBeep(void)
  48. {
  49.   tone(SPEAKER, 900,200);
  50. }
  51. // the setup function runs once when you press reset or power the board
  52. void setup() {
  53.   Serial.begin(115200);
  54.   Serial.println(“Setup radio…”);
  55.   Mirf.spi = &MirfHardwareSpi;
  56.   Mirf.init();
  57.   Mirf.payload = sizeof(radio_packet);
  58.   Mirf.channel = 2;
  59.   Mirf.config();
  60.   Mirf.configRegister(EN_AA, (1 << ENAA_P0)| (1 << ENAA_P1));
  61.   Mirf.setTADDR(tx_address);
  62.   Mirf.setRADDR(rx_address);
  63.   Mirf.configRegister(SETUP_RETR, 0b0000 | 0b1111); // MAX auto re-transmit time, max 15 retries (MAX)
  64. // Setup PS2 controller:
  65.  uint8_t error=1, pressures=0,rumble=0;
  66.   Serial.println(“Connecting to PS2 controller…”);
  67.  while(error==1)
  68.  {
  69.     error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);
  70.  if(error == 0){
  71.     Serial.print(“Found Controller, configured successful “);
  72.     Serial.print(“pressures = “);
  73.  if (pressures)
  74.     Serial.println(“true “);
  75.  else
  76.     Serial.println(“false”);
  77.   Serial.print(“rumble = “);
  78.  if (rumble)
  79.     Serial.println(“true)”);
  80.  else
  81.     Serial.println(“false”);
  82.  } 
  83.  else if(error == 1)
  84.     Serial.println(“No controller found, check wiring, see readme.txt to enable debug. visit http://www.billporter.info for troubleshooting tips”);
  85.  else if(error == 2)
  86.     Serial.println(“Controller found but not accepting commands. see readme.txt to enable debug. Visit http://www.billporter.info for troubleshooting tips”);
  87.  else if(error == 3)
  88.     Serial.println(“Controller refusing to enter Pressures mode, may not support it. “);
  89.  } // End while
  90.   Serial.println(“DONE”);
  91.  uint8_t type = ps2x.readType();
  92.  switch(type) {
  93.  case 0:
  94.       Serial.print(“Unknown Controller type found “);
  95.  break;
  96.  case 1:
  97.       Serial.print(“DualShock Controller found “);
  98.  break;
  99.  case 2:
  100.       Serial.print(“GuitarHero Controller found “);
  101.  break;
  102.  case 3:
  103.       Serial.print(“Wireless Sony DualShock Controller found “);
  104.  break;
  105. }
  106.    pinMode(MY_LED, OUTPUT);
  107.    toggleLED(10, 100);
  108.    playMelody();
  109. }
  110. void toggleLED(uint8_t flashes, uint8_t spacing)
  111. {
  112.  for (uint8_t i=0; i<flashes; i++)
  113.  {
  114.     digitalWrite(MY_LED,HIGH);
  115.     delay(spacing); // in milliseconds
  116.     digitalWrite(MY_LED,LOW);
  117.     delay(spacing); // in milliseconds
  118.  }
  119. }
  120. void flushTx(void)
  121. {
  122.     Mirf.csnLow(); // Pull down chip select
  123.     Mirf.spi->transfer( FLUSH_TX );  // Write cmd to flush tx fifo
  124.     Mirf.csnHi(); // Pull up chip select
  125. }
  126. // the loop function runs over and over again forever
  127. void loop() {
  128.  enum connection_state radio_state;
  129.  long mytime=0;
  130.  uint16_t packets_sent=0;
  131.   radio_state = WAITING;
  132.   Mirf.flushRx();
  133.   flushTx();
  134.   mytime = millis();
  135.  while(1)
  136.  {
  137.   ps2x.read_gamepad(false, 0); //read controller and set large motor to spin at ‘vibrate’ speed
  138.   radioData.buttons1 = ps2x.Button(PSB_L1)<<7 | ps2x.Button(PSB_L2)<<6 | ps2x.Button(PSB_R1) << 5 | ps2x.Button(PSB_R2) << 4 | ps2x.Button(PSB_PAD_UP) << 3 | ps2x.Button(PSB_PAD_RIGHT)<<2 | ps2x.Button(PSB_PAD_DOWN)<<1 | ps2x.Button(PSB_PAD_LEFT);
  139.   radioData.buttons2 = ps2x.Button(PSB_CIRCLE)<<7 | ps2x.Button(PSB_CROSS)<<6 | ps2x.Button(PSB_TRIANGLE)<<5 | ps2x.Button(PSB_SQUARE)<<4 | ps2x.Button(PSB_START) << 2 | ps2x.Button(PSB_SELECT)<<1;
  140.   radioData.leftX = ps2x.Analog(PSS_LX);
  141.   radioData.leftY = ps2x.Analog(PSS_LY);
  142.   radioData.rightX = ps2x.Analog(PSS_RX);
  143.   radioData.rightY = ps2x.Analog(PSS_RY);
  144.  // Send radio data  
  145.           Mirf.setTADDR(tx_address);
  146.           Mirf.send((uint8_t *)&radioData);
  147.  //while(Mirf.issending());
  148.  uint8_t status, sending;
  149.           sending=1;
  150.  while(sending)
  151.  {
  152.             status=Mirf.getStatus();
  153.  if (status & ((1 << TX_DS) | (1 << MAX_RT)) ) sending=0;
  154.  }
  155.           Mirf.isSending(); // Make a call to this so that powerUpRx is called and handled correctly (could also just call powerUpRx ourselves but this feels safer)
  156. if (status & (1 << TX_DS))
  157.             packets_sent++;
  158. if (millis()-mytime>=1000)
  159. {
  160.           Serial.print(“Packets sent:”); Serial.println(packets_sent);
  161.  if (packets_sent==0) {WaitingBeep(); radio_state=WAITING;}
  162.  else if (packets_sent<200) {LowSignalBeep();radio_state=POOR;}
  163.  else if (radio_state!=GOOD) {ConnectedBeep();radio_state=GOOD;}
  164.  if (radio_state==GOOD) toggle_pin(PORTD, 6); //pin PD6 – slow flash
  165.  else if (radio_state==WAITING) PORTD |= (1<<6); // set pin high – constant if waiting (plus hear low beep)
  166.           packets_sent=0;
  167.           mytime=millis();
  168. }
  169. } // end while
  170. } // end loop

On the receiver side, we just need a simple sketch that initialises the Mirf radio with the correct RX and TX addresses, enables ACK and then waits for a packet from the PS2 remote. NanJing Top Power ASIC Corp.

DATA HOSTED WITH ♥ BY PASTEBIN.COM – DOWNLOAD RAW – SEE ORIGINAL

  1. #include <SPI.h>
  2. #include <Mirf.h>
  3. #include <nRF24L01.h>
  4. #include <MirfHardwareSpiDriver.h>
  5. struct radio_packet
  6. {
  7.  uint8_t buttons1;
  8.  uint8_t buttons2;
  9.  uint8_t leftX;
  10.  uint8_t leftY;
  11.  uint8_t rightX;
  12.  uint8_t rightY;
  13. }radioData;
  14. uint8_t rx_address[5] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7};
  15. uint8_t tx_address[5] = {0xD7, 0xD7, 0xD7, 0xD7, 0xD7};
  16. void setup() {
  17.   Serial.begin(115200);
  18.   Serial.println(“Setup radio…”);
  19.  // put your setup code here, to run once:
  20.   Mirf.spi = &MirfHardwareSpi;
  21.   Mirf.cePin = 5; // PD5 = 5 (was 8)
  22.   Mirf.csnPin = 17; // PC3 = 17 (was 7)
  23.   Mirf.init();
  24.   Mirf.payload = sizeof(radio_packet);
  25.   Mirf.channel = 2;
  26.   Mirf.config(); //powers up RX by default
  27.   Mirf.configRegister(EN_AA, (1 << ENAA_P0)| (1 << ENAA_P1));
  28.   Mirf.configRegister(RF_SETUP, 0b1111); // 2 MBps rather than 2Mps (for reasons of signal
  29.   Mirf.setRADDR(rx_address);
  30.   Mirf.configRegister(SETUP_RETR, 0b0000 | 0b1111); // MAX auto re-transmit time, max 15 retries (MAX)
  31.   Mirf.setTADDR(tx_address); 
  32. }
  33. void flushTx(void)
  34. {
  35.     Mirf.csnLow(); // Pull down chip select
  36.     Mirf.spi->transfer( FLUSH_TX );  // Write cmd to flush tx fifo
  37.     Mirf.csnHi(); // Pull up chip select
  38. }
  39. void loop() {
  40.  static long mytimer=0;
  41.  static uint8_t index=0,sending=0; // start not sending
  42.  uint16_t packet=0;
  43.  long mytime=millis();
  44.  struct radio_packet old_packet;
  45.  while(1)
  46.  {
  47.  if (Mirf.dataReady())
  48.  {
  49.      Mirf.getData((uint8_t*) &radioData); // transfer all data (payload = 1 in this case)
  50. if (radioData.buttons1!=old_packet.buttons1) Serial.println(“Buttons 1 changed!”);
  51. if (radioData.buttons2!=old_packet.buttons2) Serial.println(“Buttons 2 changed!”);
  52.      old_packet=radioData;
  53. /*Serial.println(“****************************************”);
  54.      Serial.println(radioData.buttons1,BIN);
  55.      Serial.println(radioData.buttons2,BIN);
  56.      Serial.print(radioData.leftX);Serial.print(“,”); Serial.print(radioData.leftY);Serial.print(“,”);
  57.      Serial.print(radioData.rightX);Serial.print(“,”); Serial.println(radioData.rightY);*/
  58.      packet++;
  59.  }
  60.  if (millis()-mytime>=1000)
  61.  {
  62.     Serial.print(“Packets per second:”); Serial.println(packet);
  63.       packet=0;
  64.       mytime=millis();
  65.  }
  66.  }
  67. }

Others controls: Rota evolution, A evolução dos videogames: uma linha do tempo da história do brinquedo, Jogo com 18 quintilhões de planetas exploráveis, A história do Linux – História da Tecnologia

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s