terça-feira, 16 de abril de 2013

Atraso do Curso Arduino Automation - Dilema do ENC28J60

Pessoal,

Estou aqui, ainda atrasado com o lançamento da aula inaugural do Curso Arduino Automation, e resolvi escrever esse post, com um diário dos meus últimos 15 dias.

Finalmente estou finalizando o trabalho que venho desenvolvendo com essa versão de Ethernet Shield conhecida por ENC28J60, que nada mais é senão um chip da Microchip que ajuda a resolver a camada de rede (Ethernet).

Datasheet do ENC28J60: http://ww1.microchip.com/downloads/en/devicedoc/39662b.pdf

Como podemos verificar no datasheet ele é entitulado de Stand-Alone Ethernet Controller with SPI Interface. Isso significa que ele se denomina um controlador Ethernet independente, e que disponibiliza uma interface SPI para comunicação, com o Arduino ou outro microcontrolador.

O grande problema desse modelo de Ethernet Shield é a biblioteca! O modelo W5100 de Ethernet Shield tem sua a biblioteca oficial sendo distribuida junto com o programa do Arduino. Já o ENC28J60, não existe uma biblioteca oficial, e as versões que existem sempre empacam no mesmo problema:


  • Buffer pequeno e limite envio na comunicação impedem o envio de HTML com mais de 500 caracteres*.

* Buffer de 500 bytes para o Arduino UNO e 1500 bytes para o Arduino MEGA.

Comparando o datasheet do ENC28J60 com o que está implementado em sua biblioteca para Arduino, nota-se que faltam muitas funções; e algumas estão comentadas, sob argumento de que não funcionam, e um material adicional é sugerido para leitura.

Exemplo:


// check if a packet has been received and buffered
//if( !(enc28j60Read(EIR) & EIR_PKTIF) ){

// The above does not work. See Rev. B4 Silicon Errata point 6.
 
if( enc28j60Read(EPKTCNT) == 0 ) {
return(0);
}

Estou tentando entender como funciona esse Ethernet Shield ENC28J60 pelos últimos 15 dias. Já venho brigando com ele há tempos, mas agora é definitivo.

Já consegui as seguintes melhorias na minha biblioteca para o ENC28J60:

  • Eliminada a limitação do buffer de 500 bytes para o Arduino UNO e de 1500 bytes para o Arduino MEGA;
  • Retirada a limitação de envio de apenas um pacote TCP;
  • Mantida a limitação de apenas um socket TCP, mas com agora controle de outros sockets;
Dessa forma, agora a biblioteca pode enviar páginas grandes de HTML, em pequenos pacotes TCP de 72 (dados) + 54 (header) = 128 bytes.

Só que agora que são muitos pacotes de 128 bytes sendo enviados, então a conexão ficou um pouco demorada, mas isso é facilmente resolvido através de ajustes no timer.

Alterei a biblioteca para funcionar em um formato de Serviço, com um timer que roda a cada 5 ms e verifica se dados chegaram ou precisam ser enviados pelo socket TCP.

Esse Serviço também lida com pacotes ARP, ICMP, e novos sockets, que o cliente vai abrindo durante a conexão. Como o Arduino não tem memória suficiente para lidar com vários sockets, o Serviço vai respondendo e fechando as conexões de socket, fora da conexão principal.

Essa biblioteca que estou fazendo ainda vai precisar de muitas contribuições da comunidade e muitas versões para ainda resolver todos os bugs e implementar todas as funcionalidades, mas já é uma luz no fim do túnel para quem sempre quis utilizar esse modelo de Ethernet Shield ENC28J60.

Eu mesmo sempre fiquei revoltado de não conseguir fazer esse modelo ENC28J60 a funcionar, mas só depois que descobri que ele não é "pior" que o W5100, mas sim, ele é mais versátil, permitindo implementações mais próximas às camadas mais baixas da rede. Por outro lado, é mais difícil de implementar código e organizar em bibliotecas.

A grande motivação que me faz continuar a criar essa biblioteca para o ENC28J60 é que ele é mais portável que o W5100. Enquanto o ENC28J60 tem problemas com a biblioteca, o W5100 tem dificuldades de funcionar em algumas versões de Arduino, principalmente se for uma versão stand-alone, tipo Nano, Mini, Lilypad, etc.

Já o ENC28J60 tem até versão em Módulo, além do Shield:


Shield Ethernet ENC28J60 v1.1


Módulo Ethernet ENC28J60 v1.1