RC Car Hack

O objectivo do projecto é controlar um carro telecomandado (Nikko) sem ser pelo comando original, a recepção é feita através do módulo Bluetooth e de um Arduino (modelo Sippino), os dados de controlo são enviados por PC ou telemóvel. 

Primeiro tive de identificar o chip utilizado para controlar o carro, felizmente o circuito utiliza chips Realtek RX2\TX2 (pesquisando pela refª PT8A978B9 \ Z0309NW):

   

Basicamente vamos utilizar apenas 5 pinos do chip de recepção RX2:

FORWARD \ BACKWARD \ RIGHT \ LEFT \ GROUND 

(O pino VDD tem 5v)

Para garantir que nada corre mal em termos de interferências a controlar os motores (chip e Arduino), removi o chip do circuito e substituí o mesmo por um socket (no caso de um dia querer colocá-lo novamente). Agora apenas é necessário ligar o arduino aos 5 pinos anteriormente usados pelo chip e já identificados pela datasheet da Realtek (4 pinos de controlo e 1 pino de Ground que liga o negativo das pilhas do carro com o negativo do arduino alimentado com uma pilha de 9v).

Como a corrente medida nos pinos de controlo do circuito (que ligam depois aos transístores) estava um pouco instável, entre os 30 e os 60mA, por precaução coloquei umas resistências de 1K entre os pinos do arduino e o circuito do carro (pois o limite é de 40mA para os pinos do ATMega não queimarem). 

Código de teste que activa sequencialmente os pinos do circuito:

int Right= 2;

int Left= 3;

int Forward= 4;

int Backward= 5;

int PwmPin = 6;  

void setup() {                

  pinMode(Right, OUTPUT);   

  pinMode(Left, OUTPUT); 

  pinMode(Forward, OUTPUT); 

  pinMode(Backward, OUTPUT);   

  pinMode(PwmPin, OUTPUT);   

}

void loop() {

  digitalWrite(Right, HIGH);   

  delay(1000);               

  digitalWrite(Right, LOW);   

  delay(100);               

  

  digitalWrite(Left, HIGH);   

  delay(1000);              

  digitalWrite(Left, LOW);    

  delay(100);     

  

  digitalWrite(Forward, HIGH);   

  delay(1000);               

  digitalWrite(Forward, LOW);    

  delay(100);     

  

  digitalWrite(Backward, HIGH);   

  delay(1000);               

  digitalWrite(Backward, LOW);    

  delay(100);     

  

  for (int i=0; i<=255; i++) {   analogWrite(PwmPin, i); delay(10);}

}

1º teste com tudo ligado e a enviar comandos para a portal serial do Arduino através de cabo USB e do IDE:

Arduino ligado com resistências de 1K, módulo bluetooth instalado mas sem ser utilizado neste teste

Vídeo:

O teste seguinte foi ligar o módulo Bluetooth de acordo com esta página e programar uma aplicação em Visual Basic para fazer o envio de comandos Serial. A ligação bluetooth entre o PC e o módulo foi efectuada com uma PEN bluetooth da MSI, ficando assim configurada uma porta COM que pode ser utilizada depois na aplicação criada:

Vídeo de teste:

Código utilizado:

//PINOS Motor 

int Forward= 3;

int Backward= 6;

int Right= 9;

int Left= 11;

int Velocidade=100;

//int PwmPin = 6;   

//Bluetooth

char INBYTE;

void setup() {

 Serial.begin(9600); 

  //MOTOR:

  pinMode(Right, OUTPUT);   

  pinMode(Left, OUTPUT); 

  pinMode(Forward, OUTPUT); 

  pinMode(Backward, OUTPUT);   

  //pinMode(PwmPin, OUTPUT);   

  Serial.println("RC CAR LIGADO");

  }

void loop() {

  while (!Serial.available());    

  INBYTE = Serial.read();      

Serial.println(INBYTE);

  if ( INBYTE == 'V' ){Velocidade=getnumber('S');  Serial.println("Velodidade OK!"); }  //Recebe a letra 'V' seguido do número associado à velocidade

  

  if( INBYTE == '1' ) { analogWrite(Forward, Velocidade); analogWrite(Backward, 0); analogWrite(Left, 0); analogWrite(Right, 0);}  // FRENTE

  if( INBYTE == '2' ) { analogWrite(Backward, Velocidade);analogWrite(Forward, 0); analogWrite(Left, 0); analogWrite(Right, 0);} // TRÁS

  

  if( INBYTE == '3' ) { analogWrite(Forward, Velocidade); analogWrite(Right, Velocidade); analogWrite(Left, 0); analogWrite(Backward, 0);} // FRENTE + DTA

  if( INBYTE == '4' ) { analogWrite(Forward, Velocidade); analogWrite(Left, Velocidade);  analogWrite(Right, 0); analogWrite(Backward, 0);}  // FRENTE + ESQ

  

  if( INBYTE == '5' ) { analogWrite(Backward, Velocidade); analogWrite(Right, Velocidade); analogWrite(Left, 0); analogWrite(Forward, 0);} // TRAS + DTA

  if( INBYTE == '6' ) { analogWrite(Backward, Velocidade); analogWrite(Left, Velocidade);  analogWrite(Right, 0); analogWrite(Forward, 0);} // TRAS + ESQ

    

  if( INBYTE == '7' ) { analogWrite(Left, Velocidade);  analogWrite(Forward, 0); analogWrite(Backward, 0); analogWrite(Right, 0); }  // ESQUERDA

  if( INBYTE == '8' ) { analogWrite(Right, Velocidade); analogWrite(Forward, 0); analogWrite(Backward, 0); analogWrite(Left, 0);}    // DIREITA

    

  if( INBYTE == '0' ) { analogWrite(Forward, 0); analogWrite(Backward, 0); analogWrite(Left, 0); analogWrite(Right, 0);} // PARADO

 }

 long getnumber(char stop_character) {

  int cs;

  long i = 0;

  while(1) {

    while(!Serial.available())

      delay(100); // Verifica a cada 100 ms -- para não esforçar demais o CPU -- se recebeu dados

    cs = Serial.read();

    if(stop_character == (char)cs) break; // Recebe os dados e compara-os com o carácter de paragem. Se for igual, pára de receber dados.

    if(cs < '0' || cs > '9') continue; // Se não for um dígito ignoramos

    i *= 10;

    i += (cs-'0'); } // O número resultado avança uma casa decimal para cima, e adiciona o dígito lido (para obter o dígito decimal a partir do caracter, basta subtrair o caracter '0'.

  return i; }

Versão final da aplicação criada em Visual Basic:

Existe também a opção de controlar o carro com um telemóvel Android, podemos utilizar a aplicação desenvolvida pela Iteadstudio que envia também os comandos por bluetooth: "ITEAD Bluetooth Robot Panel" da mesma forma que no PC: