Olá a todos. Tudo bem?

Ontem fui premiado com a quebra do conector usb do esp8266, então, o Celso citou sobre o OTA.

Fui pesquisar, achei bastante interessante. 

Como referência, usei este tutorial: https://www.filipeflop.com/blog/programacao-esp8266-ota-wifi/

Instalei o python mais novo e o do citado no link.

Ao rodar o exemplo basicOta, tudo funciona certinho.

Depois de um tempo, tive um problema onde ele emitia um erro: "OTA [ERROR]: No Answer", que foi resolvido adicionando um capacitor eletrolítico (a recomendação era 470uf, mas eu só tinha de 3300uf , que resolveu também) no vin e gnd do módulo (esp).

Então resolvi adaptar meu código ao OTA.

para simplificar o processo, irei chamar de "Sketch OTA" e "Sketch Tiago"

1- #define, #include, variáveis, copiadas de "Sketch OTA" para "Sketch Tiago"

2- Void Setup() de "Sketch OTA" agora é "Void Setup_OTA"

3- Void Loop() de "Sketch OTA" agora é "void loop_OTA"

Agora fica mais interessante.

1) Quando adiciono o setup_OTA no topo do processo do setup(), e o loop_OTA no topo do processo do loop(), tudo funciona perfeitamente, aparecendo no "port" do arduino IDE.

2) Ao criar uma CONDIÇÃO para que o "setup_OTA" inicie (exemplo: apertar um botão, ou passar X segundos, por millis(), com o loop_OTA em outra condição, é exibido a mensagem do ip, dizendo que está pronto, entretanto, ele NÃO aparece no port do Arduino IDE.

Ai você pode perguntar:

"Tiago, então pq não deixa logo ele funcionando desde o inicio?"

R- Não faz sentido ter uma função ativa, consumindo energia, se ela não será usada no momento. O ideal é ativa-la apenas quando for ser usada.

Eu procurei informação sobre o assunto, mas não estou achando nada que me ajude.

Obs- Anexei meu código. Ele não ta bonito, falta organizar algumas coisas e otimizar várias outras coisas, mas o ponto se resume em 2 abas: 

- ESP8266_-_TESTADOR_DE_BATERIAS.ino

- OTA.ino

Exibições: 466

Anexos

Responder esta

Respostas a este tópico

Na verdade, a condição que citei ser funcional, eu não tenho mais certeza.

Estou perdido da causa do não funcionamento.

Simplesmente, não aparece no port.

Mas se eu colocar o código limpo, ele aparece.

assim não,  né Tiago...

      Virgem Santa.  George Boole  agora está revirando no túmulo,  porque você contrariou tudo que ele criou,  e esse "tudo" é simplesmente o que faz toda tecnologia digital existir e funcionar.

      Vamos ver por que?

      Na figura a seguir, mostro a função "loop"  do seu código, e vc pode ver que marquei algumas partes com cores pra ficar mais fácil me referir a estas partes:

(clique na figura para "zoom")

      Rapaz,  só de olhar o código na figura,  já me dá um arrepio daqueles de alma-penada.

      Entenda:

      1)  para que o OTA funcione, obrigatoriamente é preciso que o "setup_OTA()"  seja executado para inicializar as funcionalidades do OTA, pois é ele (na verdade o "ArduinoOTA.begin()" ) quem "cria" aquele PORT (associado a um IP) que vc vê na IDE do Arduino,  e isso deve ser feito uma única vez, já que é uma inicialização.  Então o lugar adequado pra fazer isso é no "setup" do Arduino. Ok?

          Mas não se iluda,  pois este PORT não é um Port COM "real",  ele é virtual. Ou seja, ele é na verdade a conexão a um Server  criado no modo AP do ESP8266. Portanto a IDE do Arduino é um cliente  desse Server.

      2)  mas para que o OTA funcione mesmo,  também é preciso que o "loop_OTA()",  seja rotineiramente executado,  pois é ele (na verdade o "ArduinoOTA.handle()" ) quem verifica se em algum momento foi requisitado iniciar uma atualização OTA.  Como isso ocorre?  quando vc inicia uma atualização OTA na IDE do Arduino,  a IDE "cliente" se conecta ao Server do AP do ESP8266,  e os dois trocam "figurinhas", de forma que a IDE envie para o Server o código a ser atualizado.  Por isso o "loop_OTA()"  tem que ser executado rotineiramente,  do contrário ele pode não detectar uma requisição para uma atualização OTA.  Então,  um lugar adequado pra fazer isso é no "loop" do ArduinoOk?

      3)  bem, só os itens 1)  e 2),  já mostram a vc o que precisa ser feito pra que a coisa funcione corretamente como planejado,  e quem planejou isso foram os criadores do OTA.

            Mas a coisa é um pouco pior: veja o itens seguintes.

      4)  pra determinar quando vc quer que o OTA funcione (a seu modo),  vc criou uma variável tipo "bool" de nome "OTA_ON". Por ser "bool", ela só pode assumir dois valores:  ou "0" ou "1". (ou se vc preferir:  ou "false" ou "true").  Não há como sua variável "OTA_ON"  assumir outro valor que não seja um dos dois listados.  Então para testar o "OTA_ON",  basta que vc teste verificando um dos dois valores ("0" ou "1"),  pois se não for o que vc está verificando, só poderá ser o outro.  Não há como existir um terceiro valor possível e uma terceira possibilidade de teste.

          Mas no seu código, há três possibilidades,  pois há um "if" que testa se "OTA_ON" é igual a "0", onde marquei em roxo na figura anterior (note que a parte do "millis" não muda as coisas,  pois no final das contas o resultado será "0" ou "1" de qualquer forma).  E se não for "0",  então "OTA_ON"  só pode ser  "1",  mas no seu teste vc está verificando isso de forma desnecessária marcado na cor laranja).  Mas como se não bastasse essa doidera,  vc ainda tem o "else", que seria executado caso "OTA_ON" não fosse nem "0" nem "1".  Mas como assim??????  Percebeu porque o George Boole  certamente está revirando no túmulo?

          Então veja que o que está na parte marcada em amarelo, jamais será executado,  pois como "OTA_ON"  é tipo "bool"ou será executado a parte na cor verde, ou será executada a parte na cor azul.  A parte na cor amarela, sem chance.

      5)  mas a coisa piora um pouco mais.  Como eu disse,  para que o OTA funcione, é preciso que o "setup_OTA()"  tenha sido executado antes e uma única vez.  E depois disso, o "loop_OTA()" deve ser executado rotineiramente.  Mas na lógica mostrada na figura anterior,  ou será executado a parte verde, ou será executada a parte azul.  Jamais  as duas partes serão ambas executadas.  Então já viu, né?  Não tem como o OTA funcionar naquela lógica.

        Tá bem doido isso, né?

       Nota:  sua justificativa pra não deixar o OTA sempre "ativo e consumindo energia",  não tem sentido, pois a execução rotineira do OTA é otimizada de forma a não ficar perdendo tempo caso nenhuma atualização seja requisitada (justamente pra ter o menor impacto possível no restante do código, e esse objetivo é alcançado, pois o ESP8266  é um Processador bem rápido).

      Que tal vc analisar isso melhor,  e talvez decidir fazer as coisas como elas foram planejadas para serem feitas ?

      (se vc quiser navegar no mar com a fuselagem de um avião, pode tentar, mas o avião não foi exatamente planejado pra isso, logo algum problema vc vai ter)

      Obs.:  não fique bravo comigo.  O objetivo não é ser duro com vc.  Mas que eu imagino o George Boole  revirando no túmulo, eu imagino.

      Abrçs,

      Elcids

HAHAHAA, obrigado pela sua resposta Elcids, como eu disse, o código não está otimizado, entretanto, o "else" funciona sim.

Vamos imaginar a seguinte situação:

OTA_ON =

millis() - ota_millis = 1000

o primeiro if possui 2 parâmetros:

1) OTA_ON == 0

2) millis() - ota_millis > 4000

- O primeiro será verdadeiro, pois ota_on será igual a zero.

- O segundo será falso, pois ele pede que seja SUPERIOR a 4000, entretanto, ela possui apenas 1000.

- Entre os dois parâmetros, existe o "&&", que define como sendo obrigatória que os dois parâmetros sejam verdadeiros para que o "if" retorne um "true".

- Como o primeiro é "true", e o segundo é "false", então retornará como "false", passando a bola para o "else if".

Em seguida temos o Else if:

OTA_ON == 1

- EOTA_ON é "0", ele retornará como "false", passando a bola para o "Else".

Em seguida temos o "Else" 

- Pelos valores citados, este código será executado.

E, efetivamente, ele é executado.

Com relação ao item 5)

No código atual, o que acontece é o seguinte:

- Primeiro as condições do Else são cumpridas, então as funções que estão nele, são executadas perfeitamente.

- Após 4 segundos (pelo exemplo do código), o primeiro IF é iniciado, fazendo a chamada do Setup_OTA. A tela de LCD fica preta, é mostrada a inicialização (booting, ready, ip atual...). Ao término, ele define o "OTA_ON = 1". Impossibilitando que ele execute uma segunda vez. (perfeito)

Veja que cumpre exatamente o que você citou: "é preciso que o "setup_OTA()"  tenha sido executado antes e uma única vez".

- Aqui, o "else if" será verdadeiro (OTA_ON == 1). o loop_OTA() seria executado o tempo todo. 

Neste ponto, a única coisa ativa (no loop) seria, justamente, o "ArduinoOTA.handle()". 

"Mais nada ficaria rodando" além dele (isso é intencional).

Entretanto, ontem, ao olhar o roteador, não existia o ip citado conectado a ele, mesmo tendo informado um ip. E ai estourou minha mente.

Com relação a sua nota:

Eu não tinha conhecimento sobre isso. Mas gosto da ideia de iniciar este recurso apenas quando for necessário.

Com relação a ficar chateado:

Não tenho motivos. Você ta agregando conhecimento.

Onde exatamente o problema estava? eu não sei.

Mas comecei a organizar o código, e não foi apresentando problema me nenhum momento. Mágica? não, provavelmente algum detalhe que deixei passar. Em todo caso, está funcional.

O problema está resolvido, entretanto, não tenho certeza da solução.

Olá, Tiago!

"Teoria é quando tudo se sabe, mas nada funciona"

"Prática é quando tudo funciona e ninguém sabe porquê"

Aqui em casa eu alio Teoria e Prática: Nada funciona e eu não sei porquê!


D.T. Ribeiro.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço