Ir para conteúdo
  • Cadastre-se

dev botao

Erro na leitura de satatus do POS Sweda


Intelliware
  • Este tópico foi criado há 3019 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

  • Membros Pro

Bom dia,

Possuímos para testes uma impressora não-fiscal Sweda, modelo SI-300S configurada para o modo EPSON. A impressão de textos, qrCode e código de barras ocorrem normalmente, tanto com o Fortes Report, quanto no ESCPOS. No entanto, falhas de leitura ocorrem ao tentar verificar o status por meio da função "ACBrPosPrinter.LerStatusImpressora" que cai na "TACBrEscPosEpson.LerStatus", que atrapalham bastante pois antes de cada impressão, verificamos o status da impressora. Em debug, noto que as exceções ocorrem em pontos diferentes desta função. Já tentamos diminuir buffer da porta serial emulada e mesmo ligando diretamente um uma porta física do computador, ocorre o mesmo problema. Segue em anexo um log (log.txt) gerado pelo ACBrPosPrinter - teste.

Desde já, agradeço.

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Exato, não há mensagem de erro, mas retorna o status [stErro] ora de forma aleatória, ora logo após mandar ativar.Veja o retorno ao mandar  ler o status várias vezes seguidas na figuras em anexo. Note que retorna também "stGavetaAberta", "stTampaAberta" erroneamente. Na função "TACBrEscPosEpson.LerStatus", retorna [stErro] justamente na exceção.

 

Capturar.PNG

Capturar2.PNG

Link para o comentário
Compartilhar em outros sites

  • Fundadores

Leia os fontes de "procedure TACBrEscPosEpson.LerStatus(var AStatus: TACBrPosPrinterStatus);"

Observe que algumas situações do case, onde o "stErro" é ligado... Ou seja, a resposta da impressora, vem com os Bits ligados, causando essa interpretação

....
    if TestBit(B, 5) then
      AStatus := AStatus + [stErro];  // Waiting for online recovery   
....

 

Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

  • Fundadores

Humm.. então provavelmente o problema seja TimeOut... o default utilizado é 500... experimente mudar para:

    B := Ord(fpPosPrinter.TxRx( DLE + EOT + #1, 1, 1000 )[1]);

 

Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

  • Fundadores

Aumente para 2 segundos (2000), observe se ele está realmente usando a versão modificada (na dúvida rode novamente o ACBrInstall)

Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Aumentamos para 2s e até para 20s e o problema continua da mesma forma.

Capturei o erro gerado pela exceção e realmente diz sobre o timeout: 'Communication error 9997: Timeout during operation'.

O estranho que mesmo com o timeout alto, não altera o tempo da leitura, o que talvez não esteja chegando ao final do mesmo. Confirmei em debug que o novo valor inserido está sendo passado para as funções subsequentes.

Link para o comentário
Compartilhar em outros sites

  • Fundadores

parece ser algo do equipamento, as vezes ele não está pronto para receber o comando... O que podemos implementar, é um Loop de contador de falhas...

Ou seja, ele ficaria preso na rotina, por N vezes, até conseguir ler, ou atingir N...   tente com essa implementação

 

procedure TACBrEscPosEpson.LerStatus(var AStatus: TACBrPosPrinterStatus);
var
  B: Byte;
  Falhas: Integer;
begin
  if not (fpPosPrinter.Device.IsSerialPort or fpPosPrinter.Device.IsTCPPort) then
    exit;

  Falhas := 0;
  while Falhas < 5 do
  begin
    try
      fpPosPrinter.Ativo := True;

      B := Ord(fpPosPrinter.TxRx( DLE + EOT + #1, 1, 500 )[1]);
      if not TestBit(B, 2) then
        AStatus := AStatus + [stGavetaAberta];
      if TestBit(B, 3) then
        AStatus := AStatus + [stOffLine];
      if TestBit(B, 5) then
        AStatus := AStatus + [stErro];  // Waiting for online recovery
      if TestBit(B, 6) then
        AStatus := AStatus + [stImprimindo]; // Paper is being fed by the paper feed button

      B := Ord(fpPosPrinter.TxRx( DLE + EOT + #2 )[1]);
      if TestBit(B, 2) then
        AStatus := AStatus + [stTampaAberta];
      if TestBit(B, 3) then
        AStatus := AStatus + [stImprimindo]; // Paper is being fed by the paper feed button
      if TestBit(B, 5) then
        AStatus := AStatus + [stSemPapel];
      if TestBit(B, 6) then
        AStatus := AStatus + [stErro];

      B := Ord(fpPosPrinter.TxRx( DLE + EOT + #4 )[1]);
      if TestBit(B, 2) and TestBit(B, 3) then
        AStatus := AStatus + [stPoucoPapel];
      if TestBit(B, 5) and TestBit(B, 6) then
        AStatus := AStatus + [stSemPapel];

      Break;
    except
      Inc( Falhas );
      if Falhas >= 5 then;
        AStatus := AStatus + [stErro];
    end;
  end;
end;

 

 

Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Daniel, boa tarde!

Hoje fuçamos um pouco mais sobre este problema e aparentemente conseguimos solucioná-lo, modificando a função "TACBrPosPrinter.TxRx". Primeiramente, limpamos o buffer da porta serial antes do envio dos comandos, resolvendo cerca de 50% dos retornos errôneos. Depois colocamos um "sleep" de 10ms (com 2ms já resolveu) entre a transmissão e a recepção dos bytes, solucionando 100% dos retornos errôneos. Segue o bloco modificado:

function TACBrPosPrinter.TxRx(ACmd: AnsiString; BytesToRead: Byte;
  ATimeOut: Integer; WaitForTerminator: Boolean): AnsiString;
begin
  if FDevice.IsSerialPort then FDevice.Serial.Purge;

  GravarLog('TX -> '+ACmd, True);
  FDevice.EnviaString( ACmd );

  if FDevice.IsSerialPort then Sleep(10);

  if WaitForTerminator then
    Result := FDevice.LeString(ATimeOut, 0, chr(BytesToRead))
  else
    Result := FDevice.LeString(ATimeOut, BytesToRead);

  GravarLog('RX <- '+Result, True);
end;

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 3019 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...