Postagem em destaque

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I

Este post é o primeiro de uma série de seis que escrevi tratando de controle de potência e PID (controle proporcional, integral e derivativo...

domingo, 27 de janeiro de 2013

Leitor de código de barras com Arduino II - "agora sem as mãos!!!"




.






Nesse projeto do TCC da máquina de aplicar cola, os caras trouxeram um leitor de código de barras mais antigo, desses que usavam aqueles conectores PS/2, redondinhos desse aí do lado.

O dito até tinha um adaptador PS/2-USB, mas aí surgiu a ideia: e se a gente economizasse o custo do shield conectando o leitor direto ao Arduino, dispensando o shield USB?

Pesquisa daqui e dali, achei uma lib para conexão de teclado com esse tipo de conector ao Arduino. Como esse tipo de leitor usava a interface de teclado para se conectar ao PC, achei que funcionaria, mas... nada.

Daí resolvi analisar esse tipo de conexão em profundidade.



Essa é a pinagem do plug fêmea. Tem-se dois pinos para alimentação, um de clock e o de dados. O cabo, por sua vez, tem as duas pontas, macho e fêmea, porque ele é feito para ser conectado "em paralelo" com um teclado. A ideia é que o scanner lê a etiqueta e "digita" os dados no micro, ou seja, o computador recebe os dados como se fossem digitados.

Nosso primeiro teste foi tentar acessar os dados usando-se o conector fêmea (onde seria conectado o teclado). Tentamos usar primeiro uma lib que é usada para conectar teclado com esse tipo de plug ao Arduino, mas não funcionou. E faz sentido, já que essa extremidade é onde seria conectado o teclado, ou seja, é um plug de entrada, não de saída.
Aí, pesquisa dali e daqui, achei um site onde o cara dava a sugestão de se cortar a ponta fêmea do cabo e conectá-la com o Arduino, em seguida conectando a ponta macho que ficou ligada ao scanner à ponta fêmea. Assim foi feito:



Esse é o scanner, tipo revólver, visto de cima.


Esse é o 


Esta é o leitor conectado ao Arduino.

E... funcionou!


Abaixo, os fontes que usei, que vieram daqui.

 /*  
 Barcode Scanner                              
      This code reads the input from a ps/2 keyboard or keyboard-like      
      device (e.g. a barcode scanner), translates the scan-codes into      
      numbers (only numbers from 0 to 9 can be used at the moment)        
      It is nowhere near a complete implementation of the ps/2 protocol,     
      but it should give you a starting point.                  
      mys .// Benjamin Maus     ( benjamin.maus <at> allesblinkt.com )       
      2007                                    
 */  
 int SCAN_ENTER = 0x5a; int SCAN_BREAK = 0xf0;  
 int breakActive = 0;  
 int clockPin = 3; // Clock is only output.   
 int dataPin = 2; // The data pin is bi-directional  
                     // But at the moment we are only interested in receiving    
 int ledPin = 13; // When a SCAN_ENTER scancode is received the LED blink  
 int clockValue = 0; byte dataValue;  
 byte scanCodes[10] = {0x45,0x16,0x1e,0x26,0x25,0x2e,0x36,0x3d,0x3e,0x46}; char characters[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};  
 int quantityCodes = 10;  
 char buffer[64] = {};     // This saves the characters (for now only numbers)   
 int bufferPos = 0;   
 int bufferLength = 64;  
 void setup() {  
      pinMode(dataPin, INPUT);                          
      pinMode(clockPin, INPUT);                         
      pinMode(ledPin, OUTPUT);                          
      Serial.begin(9600);                            
 }  
 void loop() {  
      dataValue = dataRead();                          
      // If there is a break code, skip the next byte              
      if (dataValue == SCAN_BREAK) {                       
           breakActive = 1;                             
      }                                     
      // Translate the scan codes to numbers                   
      // If there is a match, store it to the buffer               
      for (int i = 0; i < quantityCodes; i++) {                      
           byte temp = scanCodes[i];                        
           if(temp == dataValue){                          
                if(!breakActive == 1){                         
                     buffer[bufferPos] = characters[i];                  
                     bufferPos++;                             
                }                                   
           }                                    
      }                                     
      //Serial.print('*'); // Output an asterix for every byte          
      // Print the buffer if SCAN_ENTER is pressed.               
      if(dataValue == SCAN_ENTER){                        
           Serial.print("\nbuffer: ");                       
           // Read the buffer                            
           int i=0;                                                                                                         
           if (buffer[i] != 0) {                          
                while(buffer[i] != 0) {                        
                     Serial.print( buffer[i] );                      
                     buffer[i] = 0;                            
                     i++;                                 
                }                                   
           }                                    
           Serial.println(" [Enter]");                       
           bufferPos = 0;                              
           // Blink the LED                                 
           digitalWrite(ledPin, HIGH);                       
           delay(300);                               
           digitalWrite(ledPin, LOW);                        
      }                                     
      // Reset the SCAN_BREAK state if the byte was a normal one         
      if(dataValue != SCAN_BREAK){                        
           breakActive = 0;                             
      }                                     
      dataValue = 0;                               
 }  
 int dataRead() {  
      byte val = 0;                               
      // Skip start state and start bit                     
      while (digitalRead(clockPin)); // Wait for LOW.              
      // clock is high when idle                         
      while (!digitalRead(clockPin)); // Wait for HIGH.             
      while (digitalRead(clockPin)); // Wait for LOW.              
      for (int offset = 0; offset < 8; offset++) {                
           while (digitalRead(clockPin));     // Wait for LOW          
           val |= digitalRead(dataPin) << offset; // Add to byte          
           while (!digitalRead(clockPin));    // Wait for HIGH         
      }                                     
 // Skipping parity and stop bits down here.                
      while (digitalRead(clockPin));      // Wait for LOW.         
      while (!digitalRead(clockPin));     // Wait for HIGH.         
      while (digitalRead(clockPin));      // Wait for LOW.         
      while (!digitalRead(clockPin));     // Wait for HIGH.         
      return val;                                
 }