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;                                
 }  

Comentários

  1. Olá cara. Muito legal seu projeto e o blog (Inclusive eu o favoritei). Não tenho muito conhecimento sobre leitores de código de barras, mas ele usado com o Arduino "baratearia" seu custo para o uso no comércio etc? Abraços e parabéns.

    ResponderExcluir
    Respostas
    1. Macksterrr, obrigado pelas palavras gentis.
      Quanto a baratear o uso no comércio: nesse caso acho que não acontece. Isso porque geralmente no comércio vc tem um PC, e o leitor pode então ser conectado a ele. Isso dispensaria o Arduino.
      A minha alternativa ajuda no caso de um equipamento que não tenha um PC conectado, que é o caso do equipamento que estamos construindo.

      Excluir
  2. Olá Mauro,
    Primeiro parabéns pelo post. Me ajudou muito. Mas queria saber se você encontrou solução para o problema do código de leitura da serial parar? Assim, aqui comigo ele funciona, funciona e de repente não lê mais. Aconteceu isso com você? Tem uma solução? Se tiver como responder para uasden@gmail.com fico grato.

    ResponderExcluir
  3. Ola meu nome é Adriano, gostei da sua explicação. Queria saber se é possível trocar somente o cabo PS/2 para o USB apenas soldando as extremidades dos fios? é que o meu cabo esta danificado e ele usa a conexão PS/2, e queria aproveitar e passar ele para USB. Obrigado.

    ResponderExcluir
  4. olá muito legal esse projeto estou tentando adicionar o alfabeto para ficar mas completo e não estou entendendo esses números, de onde você tirou?

    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'};

    ResponderExcluir
    Respostas
    1. Bom que vc gostou, Mayko. Agora nã ofui eu que tirei, foi o Benjamin Maus, autor do fonte acima.
      A maioria dos formatos de código de barras só tem número.

      Excluir
  5. ola Mauro parabens pelo post, preciso fazer um projeto na empresa onde trabalho, com leitor usb Comtac ps-950, fiz seu codigo mas nao aparece leitura no serial monitor, poderia me dar uma ajuda, mateuscardoso316@gmail.com, whatsapp 48 9622-4752, se pudece me ajudar agradeceria....

    ResponderExcluir
    Respostas
    1. Anônimo, obrigado pela visita.
      O código acima não serve para leitor USB, eu acho, apenas para leitor com esse tipo de conector que eu mostrei.

      Eu acho que vc vai ter que pesquisar algum tipo de código específico para USB. Nem sei se vai funcionar, depende do Arduino porque em alguns a porta USB nem é uma USB verdadeira, mas uma porta serial ligada a um plug USB.

      O Arduino Yún poderia ser usado.

      Excluir
  6. ai galera de AaZ http://www.computer-engineering.org/ps2keyboard/scancodes3.html

    ResponderExcluir
  7. byte scanCodes[36] = {0x45,0x16,0x1e,0x26,0x25,0x2e,0x36,0x3d,0x3e,0x46,0x1c,0x32,0x21,0x23,0x24,0x2b,0x34,0x33,0x43,0x3b,0x42,0x4b,0x3a,0x31,0x44,0x4d,0x15,0x2d,0x1b,0x2c,0x3c,0x2a,0x1d,0x22,0x35,0x1a};
    char characters[36] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'k', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

    ResponderExcluir
  8. nas correções ele não para de ler. mas as vezes na carreira le errado

    ResponderExcluir
  9. Este comentário foi removido pelo autor.

    ResponderExcluir
  10. galera essa parte de travar e não ler o codgo corretos as vezes correi atrás falta uma coisa no projeto 2 resistor de 2k2 ,
    http://playground.arduino.cc/ComponentLib/BarcodeScanner

    ResponderExcluir
  11. gostei muito do projeto, mas tenho uma duvida em meu tcc vamos fazer uma esteria selecionadora por codigo de barras, gostaria de saber qual a variavel q o valor lido é guardado , pois no meu projeto se ele ler um certo codigo vai ativar o pistao 1 por exemplo , ja lendo outro codigo acionaria o pistao dois , teria uma ideia de cm fazer?

    ResponderExcluir
  12. Testei e rodou perfeitamente.Gostaria de saber se dá pra usar com mouse que usa tomada serial RS232.Tem como responder?Obrigado.

    ResponderExcluir
  13. É um leitor LS1220 que fica ligado direto.Ele quando encontra um codigo, lé e uma luz de confirmação acente e ele bipa.

    ResponderExcluir
  14. É um leitor LS1220 que fica ligado direto.Ele quando encontra um codigo, lé e uma luz de confirmação acente e ele bipa.
    Fiz funcionar o arduino com esse leitor, se quiser saber meu email é tatiaravsantos@gmail.com

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

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

Dividindo um programa (sketch) do Arduino em mais de um arquivo

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