Como fazer um sistema de rastreamento de caminho sem fio usando mouse, XBee e Arduino- (Parte 43/49)

As aplicações do microcontrolador não se limitam ao controle de simples dispositivos elétricos ou eletrônicos, mas são amplamente utilizados nas indústrias robótica e automotiva atualmente. Desde o simples controle do espelho retrovisor até funções complexas de controle do motor são realizadas pelo microcontrolador. O microcontrolador pode até implementar o controle automático do veículo sem um motorista humano dentro dele e esses tipos de veículos são chamados de Veículos Não Tripulados (UV). Os UVs são comumente usados ​​nos campos de pesquisa, militar, resgate e agricultura. Para quaisquer UVs, o rastreamento em tempo real de seu caminho é necessário para garantir que eles estejam se movendo no caminho correto.

Este projeto demonstra como é possível fazer um dispositivo de rastreamento de trajetória mais simples para um veículo terrestre com a ajuda de um mouse óptico. O mouse óptico é um dispositivo que possui uma câmera muito pequena em seu interior que pode detectar o movimento do solo abaixo dele e comunicar a mudança na coordenada XY com um dispositivo externo por meio de protocolos simples de comunicação serial. Este projeto utiliza um mouse óptico que funciona no protocolo PS2 e tem interface com uma placa Arduino para ler os dados dele. Os dados do mouse são então transmitidos sem fio usando um par de transceptores Xbee para um computador distante, onde os dados são exibidos graficamente como uma trilha na qual ocorre o movimento do mouse.

O Xbee é a marca de um dispositivo transceptor sem fio que funciona no protocolo ZigBee. O ZigBee é o nome de um protocolo sem fio mantido pelo padrão IEEE 802.15. Este é um protocolo especificado para redes de área pessoal (PAN) sem fio usando transceptores sem fio de baixa potência. Eles também podem ser usados ​​para sistemas simples de comunicação ponto a ponto.

Dois módulos transceptores da série Xbee S1 são utilizados neste projeto, e a imagem do mesmo módulo é mostrada na figura a seguir. Como o passo dos pinos dos módulos não é compatível com a placa de ensaio, pode-se usar as placas de design baseadas em Xbee, que vêm com pinos compatíveis com a placa de ensaio.

Fig. 2: Módulo Transceptor Série Xbee S1

Como os módulos Xbee se comunicam usando protocolo de comunicação serial com os dispositivos de interface, eles podem ser conectados a um microcontrolador usando um mínimo de quatro pinos, fonte de alimentação e aterramento, saída de dados UART e entrada de dados UART. O pino número 2, UART Data Out está conectado ao pino RX1 da placa Arduino pro mini e o pino número 3, UART Data está conectado ao pino TX0.

Neste projeto é utilizada a placa Arduino pro-mini, que vem pré-programada com o Arduino carregador de inicialização. O IDE de programação usado para este projeto é o Arduino IDE versão 1.0.3 no sistema operacional Windows. A imagem da placa Arduino pro-mini e do Arduino IDE é mostrada a seguir:

Fig. 3: Placa Arduino Pro-Mini típica

Fig. 4: Janela do software Arduino IDE

Outro hardware que pode realizar a conversão de USB para TTL é usado para carregar o programa na placa Arduino. Esta placa também pode ser utilizada quando for necessária a realização de comunicação serial entre o PC e a placa Arduino.

5: Placa conversora USB para TTL externa para programação Arduino e comunicação serial

Presume-se que o leitor tenha passado pelo projeto como começar com o arduino e fiz todas as coisas discutidas nele.

O mouse PS2 usa uma comunicação síncrona com o PC que é muito semelhante ao protocolo Two Wire Interface. O conector PS2 possui um pino para Dados e outro pino para Relógio e usando apenas esses dois pinos o mouse se comunica com o dispositivo host. O mouse sempre possui um conector mini-DIN macho de 6 pinos para interface PS2 e o dispositivo host sempre possui o pino fêmea correspondente. As imagens e pinagens dos conectores macho e fêmea PS2 são mostradas na imagem a seguir:

A imagem do pino masculino do PS2

6: Conector macho mini-DIN de 6 pinos para interface PS2

A imagem do pin feminino do PS2

Fig. 7: Plugue conector fêmea Mini DIN de 6 pinos para interface PS2

A pinagem dos conectores macho e fêmea PS2

Fig. 8: Pinagem dos conectores PS2 macho e fêmea

Quando se trata de conectar o conector fêmea à placa de circuito, deve-se conseguir identificar os pinos na parte inferior do conector PS2 e a imagem a seguir será útil.

Fig. 9: Parte inferior do conector fêmea Mini DIN para interface PS2

O código escrito para este projeto usa o arquivo de biblioteca PS2 personalizado chamado “PS2Mouse.h” que possui todas as rotinas necessárias para acessar um mouse PS2. Existem duas funções que o usuário pode utilizar diretamente em seu código: “mouse.initialize ” e “mouse.report (data)”. O método de leitura dos dados do mouse PS2 usando as funções e decodificação acima para obter as coordenadas XY são explicadas em um projeto anterior em como fazer a interface de um mouse PS2 com o Arduino.

A implementação do projeto que pode receber os dados do mouse PS2 e transmitir a coordenada XY extraída dos dados do mouse através do Xbee é representada pelo seguinte diagrama de blocos:

Fig. 10: Diagrama de blocos do sistema de rastreamento de caminho sem fio usando mouse e Xbee com Ardiuno

O código escrito para este projeto no Arduino lê os dados do mouse PS2 continuamente e grava os dados no Xbee para transmissão com a ajuda das funções de comunicação serial fornecidas pelo Arduino IDE. As funções como Serial.begin que ajuda a inicializar a porta serial com uma determinada taxa de transmissão, Serial.write para enviar dados para a porta serial, funções Serial.available e Serial.read para ler dados da porta serial são utilizados neste projeto e já foram discutidos em projetos anteriores em como fazer comunicação serial com o Arduino, como enviar e receber dados seriais usando arduino e como fazer depuração serial com o Arduino. O método para obter os dados XY necessários do mouse PS2 é explicado no projeto anterior em como fazer a interface de um mouse PS2 com o Arduino. O método de interface de um módulo Xbee e transmissão de dados usando-o é discutido no projeto anterior em como fazer a interface do módulo Xbee com Arduino.

O código lê centenas de conjuntos de dados do mouse de uma só vez e calcula a alteração média no valor X desses dados. Este valor médio da mudança na coordenada X é então usado para compensar a posição de um caracter '*' em uma linha que deve ser transmitida e exibida no computador distante. Assim, à medida que o mouse se move, o valor médio da mudança na direção X varia, o que varia a posição do caracter '*' na janela do monitor serial no PC distante. Como o caracter '*' é impresso continuamente cada vez em uma nova linha com uma posição de acordo com o movimento do mouse, pode-se considerá-lo semelhante à trilha desenhada que segue o movimento do mouse na direção X.

Quando a codificação estiver concluída pode-se verificar e fazer upload do código para a placa Arduino conforme explicado no projeto como começar com o Arduino. Assim que a placa é ligada, o Xbee da placa Arduino estabelece automaticamente comunicação com outro Xbee que está conectado à porta serial de um PC. A segunda placa Xbee pode ser conectada ao PC usando a mesma placa conversora USB para TTL que foi usada para programar a placa Arduino. Mova o mouse e a mudança na trilha pode ser observado usando qualquer software de monitoramento serial ou usando o próprio software de monitoramento serial do Arduino IDE conforme explicado no projeto como fazer depuração serial com o Arduino.

Código fonte do projeto

###




/*============================ EG LABS ===================================//

 Demonstration on how to wirelessly send path information data of the 

 movement of a PS2 mouse in X direction using Xbee


 The circuit:

 LCD:

 * LCD RS pin to digital pin 12

 * LCD Enable pin to digital pin 11

 * LCD D4 pin to digital pin 7

 * LCD D5 pin to digital pin 6

 * LCD D6 pin to digital pin 5

 * LCD D7 pin to digital pin 4

 * LCD R/W pin to ground

 * 10K resistor:

 * ends to +5V and ground

 * wiper to LCD pin 3

 * LED anode attached to digital output 9

 * LED cathode attached to ground through a 1K resistor


 MOUSE:

 DATA PIN TO PIN NUMBER 8

 CLOCK PIN TO PIN NUMBER 3


 XBEE:

 RX PIN OF XBEE TO TX0 PIN OF ARDUINO

 SHORT THE GROUND PINS OF ARDUINO AND XBEE

============================== EG LABS ===================================*/


#include "PS2Mouse.h"

#define MOUSE_DATA 8

#define MOUSE_CLOCK 3

// include the library code:

#include 


// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(12, 11, 7, 6, 5, 4);


// initialize the mouse library

PS2Mouse mouse(MOUSE_CLOCK, MOUSE_DATA, STREAM);


int i;

int x_acc = 0;

int pos = 0;

int data(2);

  

void setup 

{

  pinMode(9, OUTPUT);  

  

  // set up the lcd's number of columns and rows: 

  lcd.begin(16, 2);

  lcd.print("ENGINEERS GARAGE");

  lcd.setCursor(0, 1);

  lcd.print("  MOUSE to XBEE ");

  delay(2000);

  digitalWrite(9, HIGH);

  

  Serial.begin(9600);

  

  mouse.initialize ;                        // initialize the PS2 mouse connected with the Arduino

}


void loop 

{

  x_acc = 0;

  

  for(i = 0; i < 100; i ++)

  {

      do

      {

        mouse.report(data);                         // get data from the mouse

      }while(data(1) == 0); 

      x_acc += data(1);

  }

  

  //=== get the average movement in the x direction ===//

  x_acc = x_acc / 200;

  x_acc = x_acc + pos;

  

  if(x_acc > 100)

    x_acc = 100;

  else;

  //=== get the average movement in the x direction ===// 

  

  Serial.println ;

  for(i = 0; i < (100 + x_acc); i ++)

    Serial.print(" ");

  Serial.print("*");

  

  pos = x_acc;

  

}

###

Código fonte do projeto

###




//#include "WConstants.h"

#include "HardwareSerial.h"

#include "PS2Mouse.h"

#include "Arduino.h"


PS2Mouse::PS2Mouse(int clock_pin, int data_pin, int mode) {

  _clock_pin = clock_pin;

  _data_pin = data_pin;

  _mode = mode;

  _initialized = false;  

  _disabled = true;

  _enabled = false;

}


int PS2Mouse::clock_pin  {

  return _clock_pin;

}


int PS2Mouse::data_pin  {

  return _data_pin;

}


void PS2Mouse::initialize  {

  pull_high(_clock_pin);

  pull_high(_data_pin);

  delay(20);

  write(0xff); // Send Reset to the mouse

  read_byte ;  // Read ack byte 

  delay(20); // Not sure why this needs the delay

  read_byte ;  // blank 

  read_byte ;  // blank

  delay(20); // Not sure why this needs the delay

  if (_mode == REMOTE) {

    set_remote_mode ;

  } else {

    enable_data_reporting ; // Tell the mouse to start sending data again

  }

  delayMicroseconds(100);

  _initialized = 1;

}


void PS2Mouse::set_mode(int data) {

  if (_mode == STREAM) {

    disable_data_reporting ; // Tell the mouse to stop sending data.

  }

  write(data);  // Send Set Mode

  read_byte ;  // Read Ack byte

  if (_mode == STREAM) {

    enable_data_reporting ; // Tell the mouse to start sending data again

  }

  if (_initialized) {

    delayMicroseconds(100);    

  }

}


void PS2Mouse::set_remote_mode  {

  set_mode(0xf0);

  _mode = REMOTE;

}

  

void PS2Mouse::set_stream_mode  {

  set_mode(0xea);

  _mode = STREAM;

}


void PS2Mouse::set_sample_rate(int rate) {

  if (_mode == STREAM) {

    disable_data_reporting ; // Tell the mouse to stop sending data.

  }

  write(0xf3); // Tell the mouse we are going to set the sample rate.

  read_byte ; // Read Ack Byte

  write(rate); // Send Set Sample Rate

  read_byte ; // Read ack byte

  if (_mode == STREAM) {

    enable_data_reporting ; // Tell the mouse to start sending data again

  }

  delayMicroseconds(100);

}


void PS2Mouse::set_scaling_2_1  {

  set_mode(0xe7); // Set the scaling to 2:1

}


void PS2Mouse::set_scaling_1_1  {

  set_mode(0xe6); // set the scaling to 1:1

}


// This only effects data reporting in Stream mode.

void PS2Mouse::enable_data_reporting  {

  if (!_enabled) {

    write(0xf4); // Send enable data reporting

    read_byte ; // Read Ack Byte

    _enabled = true;

  }

}


// Disabling data reporting in Stream Mode will make it behave like Remote Mode

void PS2Mouse::disable_data_reporting  {

  if (!_disabled) {

    write(0xf5); // Send disable data reporting

    read_byte ; // Read Ack Byte    

    _disabled = true;

  }

}


void PS2Mouse::set_resolution(int resolution) {

  if (_mode == STREAM) {

    enable_data_reporting ;

  }

  write(0xe8); // Send Set Resolution

  read_byte ; // Read ack Byte

  write(resolution); // Send resolution setting

  read_byte ; // Read ack Byte

  if (_mode == STREAM) {

    disable_data_reporting ;

  }

  delayMicroseconds(100);

}


void PS2Mouse::write(int data) {

  char i;

  char parity = 1;

  pull_high(_data_pin);

  pull_high(_clock_pin);

  delayMicroseconds(300);

  pull_low(_clock_pin);

  delayMicroseconds(300);

  pull_low(_data_pin);

  delayMicroseconds(10);

  pull_high(_clock_pin); // Start Bit

  while (digitalRead(_clock_pin)) {;} // wait for mouse to take control of clock)

  // clock is low, and we are clear to send data 

  for (i=0; i < 8; i++) {

    if (data & 0x01) {

      pull_high(_data_pin);

    } else {

      pull_low(_data_pin);

    }

    // wait for clock cycle 

    while (!digitalRead(_clock_pin)) {;}

    while (digitalRead(_clock_pin)) {;}

    parity = parity ^ (data & 0x01);

    data = data >> 1;

  }  

  // parity 

  if (parity) {

    pull_high(_data_pin);

  } else {

    pull_low(_data_pin);

  }

  while (!digitalRead(_clock_pin)) {;}

  while (digitalRead(_clock_pin)) {;}  

  pull_high(_data_pin);

  delayMicroseconds(50);

  while (digitalRead(_clock_pin)) {;}

  while ((!digitalRead(_clock_pin))    (!digitalRead(_data_pin))) {;} // wait for mouse to switch modes

  pull_low(_clock_pin); // put a hold on the incoming data.

}


int * PS2Mouse::report(int data ) {

  write(0xeb); // Send Read Data

  read_byte ; // Read Ack Byte

  data(0) = read ; // Status bit

  data(1) = read_movement_x(data(0)); // X Movement Packet

  data(2) = read_movement_y(data(0)); // Y Movement Packet

  return data;

}


int PS2Mouse::read  {

  return read_byte ;

}


int PS2Mouse::read_byte  {

  int data = 0;

  pull_high(_clock_pin);

  pull_high(_data_pin);

  delayMicroseconds(50);

  while (digitalRead(_clock_pin)) {;}

  delayMicroseconds(5);  // not sure why.

  while (!digitalRead(_clock_pin)) {;} // eat start bit

  for (int i = 0; i < 8; i++) {

    bitWrite(data, i, read_bit );

  }

  read_bit ; // Partiy Bit 

  read_bit ; // Stop bit should be 1

  pull_low(_clock_pin);

  return data;

}


int PS2Mouse::read_bit  {

  while (digitalRead(_clock_pin)) {;}

  int bit = digitalRead(_data_pin);  

  while (!digitalRead(_clock_pin)) {;}

  return bit;

}


int PS2Mouse::read_movement_x(int status) {

  int x = read ;

  if (bitRead(status, 4)) {

    for(int i = 8; i < 16; ++i) {

      x  = (1< pinMode(pin, OUTPUT);

  digitalWrite(pin, LOW);  

}


void PS2Mouse::pull_high(int pin) {

  pinMode(pin, INPUT);

  digitalWrite(pin, HIGH);

}

**************Header File for Mouse Intefacing*****************************

#define PS2Mouse_h
#define REMOTE 1 
#define STREAM 2 
class PS2Mouse 
{ 
private: int _clock_pin; 
int _data_pin; int _mode; 
int _initialized; 
int _enabled; 
int _disabled; 
int read_byte ; 
int read_bit ; 
int read_movement_x(int); 
int read_movement_y(int); 
void pull_high(int); 
void pull_low(int); 
void set_mode(int); 

public: PS2Mouse(int, int, int mode = REMOTE); 
void initialize ;
int clock_pin ; 
int data_pin ; 
int read ; 
int* report(int data ); 
void write(int); 
void enable_data_reporting ;
void disable_data_reporting ; 
void set_remote_mode ; 
void set_stream_mode ; 
void set_resolution(int); 
void set_scaling_2_1 ; 

void set_scaling_1_1 ; 
void set_sample_rate(int); 
}; 
#endif

###

Diagramas de circuito

Diagrama de circuito fazendo um sistema de rastreamento de caminho sem fio usando mouse-XBee-Arduino

Componentes do Projeto

  • Arduino ProMini
  • LCD
  • LIDERADO
  • Resistor

Vídeo do projeto

Conteúdo Relacionado

Voltar para o blog

Deixe um comentário

Os comentários precisam ser aprovados antes da publicação.