Boa noite, ainda na batalha, porém agora estou precisando do apoio dos amigos para me ajudarem a resolver esse problema.

Tenho um código que roda perfeito utilizando o arduino Mega com a Ethernet shield W5500.

Porém preciso que o mesmo código rode na Ethernet shield ENC28J60 usando o arduino Nano.

Já tentei algumas bibliotecas, mais sem exito, pois compila mais sobrecarrega a memória do arduino nano, assim não tem espaço para trabalhar o loop na parte referente a String LINE. Segue em anexo o código, agradeço por qualquer apoio.

arduino_mega.ino

Exibições: 1115

Responder esta

Respostas a este tópico

Bom dia Elcids,

vc alterou nome da LIB nos includes ?  SIM.

Vou fazer o teste.

Segue a biblioteca que estou usando.

UIPEthernet-2.0.7.rar

TESTE%202.rtf

Segue o texto do monitor serial.

olá Thomaz.

      Antes de tudo, desculpe por não ter postado o arquivo ontem.

      Analisei o resultado do teste que eu te pedi pra fazer ontem.  Ainda bem que vc postou o arquivo com o texto "copiado" da janela do Terminal do Arduino,  pois a imagem capturada não mostra as linhas completas (e era preciso ver todo o texto enviado pelo Modem).

      O resultado confirma o que eu tinha imaginado. Em cada requisição que é feita ao Modem, este  envia ao Arduino,  mais de 700 bytes (conforme o valor "count" informado pelo código de teste). Eu analisei a LIB "UIP" nos níveis mais "baixos", e descobri que todo este bloco de dados fica inicialmente "retido" na RAM interna do ENC28J60.  Estes dados só irão para a  RAM do Arduino,  se vc ler os mesmos através da LIB "UIP" (via "read", "readStringUntil", etc). Como o bloco de dados retornado pelo Modem é relativamente grande,  é preciso ler todo seu conteúdo (pois a leitura é obrigatoriamente sequencial) e então reter apenas o que é necessário (neste caso a informação desejada, que é o Nível de Sinal).  E o código que eu implementei usando a "UIP", faz exatamente isso. Ao encontrar a informação desejada no bloco de dados, vc não precisa continuar lendo, pois ao executar o "Client.stop"  a LIB "descarta" o restante dos dados que estão na RAM interna do ENC28J60 (ficando pronto para novo ciclo).

      A própria abertura da Conexão, assim como a alocação de um Cliente,  já usa uma certa quantidade da RAM do Arduino.  Este é o motivo que eu te pedi pra enviar a versão da LIB que vc estava usando, pra que eu pudesse ver isso nessa LIB.  E de forma surpreendente,  sua LIB  "UIPEthernet-2.0.7não  é  a "oficial", ou seja, alguém alterou a mesma (eu confirmei isso analisando o código fonte). E embora a alteração seja pequena, ela economiza uma boa quantidade da RAM do Arduino.  Sobre esses detalhes, falarei posteriormente em outro post (pois esse "ajuste" pode ser feito também nas versões mais recentes da LIB "UIP").

      Assim,  não atualize  sua LIB "UIP".  Continue usando a versão "2.0.7" que vc postou aqui, a fim de permitir a economia de RAM, pois isto é fundamental.

      Mas fiquei curioso sobre isso:  onde vc encontrou essa versão "2.0.7" da LIB ?  Vc poderia informar o link ?

      Outra coisa que fiquei curioso, é sobre como vc descobriu que era "13" o índice de Parâmetros do Modem,  para o Nível de Sinal?  Vc foi comparando os dados enviados ao Arduino, com o valor que aparecia na tela do Navegador de Internet?

      Vamos à implementação.

      Nesta "versão",  está habilitado para também exibir no Terminal do Arduino, o quanto de RAM contínua  está "livre", em momentos estratégicos da execução. Esta informação é muito importante, pois ela permitirá vermos se o uso de RAM durante a execução, está muito "apertado". Vou explicar melhor.  Logo que o código é executado,  ele informa a RAM "livre" inicial  (isto é feito em dois pontos no "setup").  Então, conforme as requisições são feitas ao Modem, a RAM "livre" poderá ir diminuindo muito se o Sistema do Arduino (o "Gerenciador do Heap") não administrar isso adequadamente (às vezes não há como evitar), e então poderá ocorrer um "crash" no Sistema (e aí fica tudo "doido", podendo até "travar"). Ou seja, é preciso deixar o código executando e então acompanhar o total "livre" de RAM  informado no Terminal do Arduino.

      No Terminal, vc verá impresso assim:  (x) RAM livre = N ,  onde "x" indica o ponto do código onde aquela medição foi feita, e "N" é o total de RAM "livre" naquele momento. No "setup" os dois pontos são "(0)" e "(1)"  (os valores de "x"), e como está no início da execução, nestes pontos deve resultar a maior quantidade "livre" de RAM (os valores de "N"). Os demais pontos foram colocados estrategicamente, de forma que se possa analisar o comportamento do Sistema e "quem" está consumindo mais RAM na LIB "UIP" (já que o próprio código consome um mínimo de Memória).

      Assim, é bastante importante que vc copie o texto do Terminal do Arduino  (como vc fez anteriormente),  e post o arquivo aqui pra que eu possa analisar o comportamento do código em termos da RAM "livre" durante a comunicação com o Modem.  Não é necessário esperar muito:  bastam uns 10 a 15 segundos de execução e já é possível concluir sobre o comportamento.

      Claro, além da RAM "livre",  também é exibido no Terminal, o Nível de Sinal  enviado pelo Modem.

      Caso vc queira  desabilitar  a exibição da RAM "livre", basta fazer isso na linha do código mostrada na figura a seguir:

(clique na figura para "zoom")

      Note que na figura anterior, a exibição da RAM "livre" está habilitada.  Para desabilitar,  mude o valor ali para  "0" (zero), conforme explicado no próprio comentário na linha de código.

      Desabilitando a exibição da RAM "livre",  automaticamente  deixam de ser compiladas as linhas de código onde esta exibição é feita (ou seja, não é preciso deletar ou comentar aquelas linhas). 

      Segue o código:   "Nano_ENC28J60_00T.zip"

      Confirmando que o Sistema está estável,  então eu postarei detalhes explicando como vc pode configurar outras coisas no código (embora apenas olhando o início do código, isto fique evidente).

 

      Fico no aguardo.

      Abrçs,

      Elcids

Boa noite, Elcids

segue o link de onde eu pego as bibliotecas que preciso:

https://www.arduinolibraries.info/libraries

Nesse link existe várias versões da biblioteca UIP, eu fui testando uma a uma para ver qual era a melhor para a shield se conectar.

Eu que fiz alteração na livraria  UIP na pasta " utility " - " uipethernet-conf "  para economizar RAM, encontrei em um poste falando sobre o assunto.

Descobri a posição 13 para achar o nivel de DB da seguinte maneira: Pelo browser digitei o IP/status do modem com a antena posicionada e vi onde estava o valor de db que era igual a pagina onde é feita o alinhamento da antena.

Vou ler suas instruções com calma para fazer o teste e te retorno.

Desde já grato pelo grande apoio.

Abçs Thomaz

Boa tarde Elcids,

segue o teste,.....

teste%203%20nano.rtf

DEPOIS DE UM PERIODO LIGADO:

(6) RAM livre = 1185

Nivel de Sinal = 0 [db]

desconectado !
reconectando automaticamente ...

desconectado !
reconectando automaticamente ...

desconectado !
reconectando automaticamente ...

desconectado !
reconectando automaticamente ...

Outro teste

NOVO%20TESTE.rtf

Travou depois de um periodo. Conforme o tempo no anexo.

olá Thomaz.

      Analisei os arquivos do seu teste. Mas me concentrei no segundo arquivo (o tal "novo"), pois é muito mais significativo que o primeiro. Além disso o primeiro não tem os "timestamps" do Terminal do Arduino (estas marcações de tempo são fundamentais, mas eu esqueci de colocar algo assim no código, para o caso do "timestamp" do Terminal estar desligado).

      Vamos então às conclusões dessa análise "preliminar":

      O "travamento" que ocorreu conforme vc descreveu, eu acredito que seja por causa do uso da função "maintain" da "UIP", e explico isso mais adiante.

      Os dados impressos no Terminal,  mostram que ocorrem momentos que o "Cliente" (o Arduino) não conseguiu se conectar ao "Host" (o Modem), mas logo em seguida conseguiu a conexão, e aí o "Host' respondeu de acordo.  Estas falhas ocorrem em três momentos,  e nos dois primeiros,  o Sistema conseguiu se recuperar.  Mas na terceira, vemos que a  última mensagem foi  "não recebeu o Sinal", e depois disso nenhuma msg foi "impressa". Veja a sequência que ocorre:

   a)  25 respostas OK do Host, num período de 13 segundos.

   b)  2 falhas de conexão do Cliente, num período menor que 0.5 segundo.

   c)  14 respostas OK do Host, num período de 7 segundos.

   d)  2 falhas de conexão do Cliente, num período menor que 0.5 segundo.

   e)  15 respostas OK do Host, num período de 8 segundos.

    f)  1 falha de conexão do Cliente,  então "trava", e não há mais respostas.

      Como se vê, embora o período de teste não seja muito grande, parece que estava se formando um padrão de comportamento.  Lembrando que no teste, eram feitas requisições a cada 250 ms (ou seja, 4 vezes por segundo).

      Uma coisa muito importante, é que a RAM "livre" ficou estável o tempo todo, o que é um ótimo sinal, pois indica que a LIB "UIP"  não  está "largando" objetos no "Heap" do Arduino (se estivesse "largando" poderia levar a um "crash" do Sistema). E pela quantidade total de requisições, esta conclusão é praticamente definitiva sobre esta versão do código.

      As falhas de conexão do "Cliente",  são evidentes  porque naqueles momentos não são impressas as msgs de RAM "free" de (3) a (5), mas sempre foi impressa a msg (6).  E não foi ocorrência do "timeout" que eu implementei,  pois para isso teriam que ter sido impressas as msgs de (3) até (5).  Então sobre isso não há dúvida.

      Então o que causou o "travamento" ???   Eu tenho um palpite, e ele pode ser evidenciado na figura a seguir, que mostra uma observação que "fizeram" no código fonte da LIB "UIP", especificamente na função "maintain" (veja principalmente o texto que eu marquei em amarelo) :

(clique na figura para "zoom")

      Eu suspeito que o tratamento de algum desses "IP events",  tenha falhado por algum motivo,  e como não implementaram um "timeout" nestes casos, a função "maintain" não retorna (como explicado na figura anterior), causando o Sistema travar.  Pode ser um bug da "UIP", por que provavelmente o "maintain" é muito pouco usado (eu realmente nunca vi alguém usando isso no "UIP")  e então talvez ninguém tenha detectado isso (ou detectaram e deixaram pra lá).

      Ocorre que como o "Ethernet.begin" não está mais no "loop" do Arduino,  então eu coloquei o "maintain" executando ali, de forma a  renovar o IP automaticamente caso necessário (via DHCP como descrito na própria funcionalidade do "maintain"). Mas talvez essa não tenha sido uma boa ideia.

      Então minhas sugestões são:

      Opção 1:  usar a função "maintain" da LIB,  mas com uma temporização própria, pois atualmente ele está sendo executado logo após a conclusão de cada requisição ao Host .  E também nunca executar antes de um certo tempo depois da conclusão da comunicação com o Host.

      Opção 2:  usar a função "linkStatus" da LIB para detectar que ocorreu uma desconexão. E isto também de forma temporizada, ou seja da mesma forma que na "Opção 1".  Mas o "linkStatus" não tem o problema do "maintain".  E quando o "linkStatus" indicar uma desconexão, então usamos o "Ethernet.begin" para reconectar.  Neste caso,  é muito importante  acompanhar o  histórico das mensagens de RAM "free",  para constatarmos que após uma reconexão, a LIB "UIP"  não está alocando mais Memória, ou seja, não está gradativamente diminuindo o RAM "free" (se for diminuindo, isto pode levar ao "crash" do Sistema).

      Eu voto pela "Opção 2".  É mais radical, mas me parece mais sensata neste momento. E na "Opção 1",  nada garante que  o "maintain"  não vá causar problemas, mesmo que mais esparsos.

      Aguardo sua opinião.

      (não se preocupe, pois é tranquilo de fazer estas implementações no código)

      Abrçs,

      Elcids

Bom dia Elcids,

Fiz outro teste agora usando o roteador, e com ele não travou mais.

segue o teste....

TESTE%204.rtf

Para oque vou usar o roteador sempre estará ligado.

No momento estou fazendo os testes somente na bancada sem o modem estar ligado na antena.

Na parte da tarde vou colocar o modem ligado junto ao sistema para ver o nivel de sinal no monitor serial com a antena apontada.

Boa noite Elcids,

Fiz o teste com a antena.

segue o resultado...

TESTE%20COM%20MODEM%20LIGADO%20A%20ANTENA.rtf

* Tem como dimiuir o tempo de leitura do nivel de db?

 No momento esta na casa de 500 millis.

Graças a você o código esta ficando exelente, Nota MIL para ti.

excelente 

olá Thomaz.

      Legal que ficaram Ok os resultados dos seus novos testes.

      Eu percebi que confundi a funcionalidade da função "linkStatus", pois esta só verifica se há uma conexão de hardware estabelecida, ou seja, em suma acaba detectando apenas se o cabo de rede está conectado  e  se há um dispositivo Ethernet funcionando na "outra ponta".  Logo, para o que eu sugeri implementar na "Opção 2",  o "linkStatus" não iria adiantar. E infelizmente, na LIB "UIP" não há mais nenhuma outra funcionalidade disponível para aquela implementação (a "Opção 2"),  a não ser o próprio "maintain".

      E como eu já estava usando o "maintain",  então nessa nova versão que preparei (o código está mais à frente), eu mantive a mesma lógica que já está sendo usada nestes seus últimos testes. Apenas acrescentei a temporização para o "maintain", de forma que agora ele verifica se a conexão está Ok em intervalos bem definidos. No código que estou disponibilizando, este intervalo está definido para 15 segundos (ou seja, a cada 15 segundos o Sistema verifica se a conexão está Ok  ou se precisa renovar o IP via DHCP).  Mas vc pode mudar isso caso deseje, alterando o intervalo de tempo em segundos, conforme mostro na figura a seguir marcado em "verde":

(clique na figura para "zoom")

      Observe que se estiver funcionando bem com este intervalo, aconselho não alterar.

      Também fiz a temporização mais efetiva do intervalo de leitura do Nível de Sinal, pois antes estava cadenciando via "delay",  o que não era bom (mas quebrava o galho até aquele momento).  Sobre isso, se vc analisar os resultados "impressos" anteriormente,  vai perceber que o tempo de processamento de uma requisição e resposta do Host (o Modem), é cerca de pouco mais de 200 mili-segundos,  e vc pode checar isso olhando os intervalos do "timestamp" dos prints da "RAM livre" entre (3) e (6).  Ou seja, não adianta setar um intervalo de leitura menor que 200 [ms].  Assim deixei o intervalo de leitura em 250 mili-segundos, o que dará uma taxa de leitura de 4 vezes por segundo. Você pode alterar isso conforme mostrado na figura a seguir, salientado na cor "verde":

(clique na figura para "zoom")

      Mas como eu disse, não adianta diminuir abaixo de 200 [ms], pois este é o tempo mínimo que são processadas as requisições e respostas via LIB "UIP".

      Aproveito para colocar algumas questões que me deixaram "encafifado":

      1)   no primeiro teste que vc relatou que "travou",  será que isso ocorreu mesmo?

            Veja:  quando o "maintain" é executado,  se o Modem  parar de responder, então o "maintain" fica aguardando por até 1 minuto (este tempo está definido na LIB "UIP").  Assim se vc não aguardar esse tempo,  poderá achar que "travou", quando na realidade isso não ocorreu (e depois de 1 minuto, vai ver a mensagem no Terminal de que o Sistema está desconectado e que irá reconectar automaticamente).

      2)  se vc está usando um Computador conectado ao Arduino, e consegue ver o Nível de Sinal  via  Navegador de Internet (ex.: Chrome), então porque vc precisa ver isso através do Terminal do Arduino?

           Minha suspeita:  no Navegador de Internet, vc tem que ficar atualizando a página, o que é um inconveniente. Além disso no navegador vem aquele "monte " de informações,  o que dificulta a visualização do Nível de Sinal.  Se for algo assim,  posso implementar um APP  para ver isso no Celular, e assim dispensar o Arduino. No APP  seria exibido apenas o Nível de Sinal, em letras grandes para ficar fácil de ler.

      3)  uma possibilidade ao invés de ter o Arduino  sempre conectado ao Computador,  seria  acrescentar  um  Display LCD 16x2   desses "convencionais"  via  I2C,  e assim exibir o Nível de Sinal neste Display (além de outras informações do Sistema).  Vc não acha isso viável para o seu caso?

      4)  vc poderia postar uma foto do seu módulo ENC28J60 ?

          Eu gostaria de ver qual dos diversos módulos existentes no mercado, vc está usando.

      Muito importante:  por favor, quando vc enviar arquivos com os resultados,  peço para  não desligar  a exibição da "RAM livre",  pois isso é muito importante para a análise do que está ocorrendo. Claro, também não esqueça de habilitar o "timestamp" no Terminal do Arduino.

      Veja:  os tempos de transmissão dos dados para o Computador são muito pequenos (menos de 10 ms quando é exibido o Nível de Sinal),  então não precisa se preocupar pois isso não interfere na performance do Sistema.

      Uma dica:   para facilitar copiar o texto do Terminal do Arduino, faça assim:  clique com o "mouse" na janela de texto do Terminal, e então use as teclas "control  a"  para selecionara todo o texto.  Então  com todo o texto selecionado, use as teclas "control  c" para copiar esse texto.

      Se possível, "registre"  uns 2 minutos de operação, postando aqui o arquivo com este registro para que eu possa analisar o resultado.

      Segue o código atualizado:   "Nano_ENC28J60_01T.zip" 

      Abrçs,

      Elcids

olá Thomaz.

    No código fonte "acima" (o "Nano_ENC28J60_01T"), um valor ficou com um zero a mais quando o digitei (na linha 293). Eu percebi numa simulação que fiz pra testar o mesmo.

    Assim, segue o código "corrigido":   "Nano_ENC28J60_01T.zip"

    Abrçs,

    Elcids

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço