Alguém para me ajudar trocar Delay por Millis - Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)2024-03-28T21:39:37Zhttps://labdegaragem.com/forum/topics/algu-m-para-me-ajudar-trocar-delay-por-millis?commentId=6223006%3AComment%3A871434&x=1&feed=yes&xn_auth=noOk Marcela.
No código…tag:labdegaragem.com,2021-07-15:6223006:Comment:8714342021-07-15T12:08:37.492ZElcids Chagashttps://labdegaragem.com/profile/ElcidsChagas
<p><span style="font-size: 12pt;">Ok Marcela.</span></p>
<p></p>
<p><span style="font-size: 12pt;"> No código que eu postei, está uma implementação completa exatamente com a mesma funcionalidade do seu código original, porém sem usar delay no loop do Arduino. Nos <em><strong>vídeos</strong> </em>das <em><strong>Simulações</strong></em>, que também postei, vc pode conferir o funcionamento.</span></p>
<p></p>
<p><span style="font-size: 12pt;"> Atente exclusivamente para o código no…</span></p>
<p><span style="font-size: 12pt;">Ok Marcela.</span></p>
<p></p>
<p><span style="font-size: 12pt;"> No código que eu postei, está uma implementação completa exatamente com a mesma funcionalidade do seu código original, porém sem usar delay no loop do Arduino. Nos <em><strong>vídeos</strong> </em>das <em><strong>Simulações</strong></em>, que também postei, vc pode conferir o funcionamento.</span></p>
<p></p>
<p><span style="font-size: 12pt;"> Atente exclusivamente para o código no <strong><em>loop</em> </strong>do <em><strong>Arduino</strong></em> (e <span style="text-decoration: underline;"><em>não se preocupe</em></span> com o restante das funções), e aí <span>certamente</span> vc vai entender (e sem esforço) o que precisa fazer.</span></p>
<p></p>
<p><span style="font-size: 12pt;"> Mas não deixe de perguntar aqui, caso tenha alguma dúvida.</span></p>
<p></p>
<p><span style="font-size: 12pt;"> Abrçs,</span></p>
<p><span style="font-size: 12pt;"> Elcids</span></p> Boa noite Elcids, faz tempo m…tag:labdegaragem.com,2021-07-15:6223006:Comment:8713512021-07-15T01:32:43.088Zmarcela de souzahttps://labdegaragem.com/profile/marceladesouza
<p>Boa noite Elcids, faz tempo mesmo , fiquei um bom tempo sem mexer com Arduíno, Obrigada pela atenção, vou dar uma estudada sobre Maquina de estados </p>
<p>Boa noite Elcids, faz tempo mesmo , fiquei um bom tempo sem mexer com Arduíno, Obrigada pela atenção, vou dar uma estudada sobre Maquina de estados </p> olá novamente Marcela.
…tag:labdegaragem.com,2021-07-14:6223006:Comment:8713412021-07-14T16:18:40.117ZElcids Chagashttps://labdegaragem.com/profile/ElcidsChagas
<p><span style="font-size: 12pt;">olá novamente Marcela.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Faz algum tempo que não "conversamos" aqui.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Vi o código que vc postou, e fiz uma implementação correspondente, sem usar os diversos delays que originalmente vc usou. Mas antes de falar sobre esta implementação, seguem algumas…</span></p>
<p><span style="font-size: 12pt;">olá novamente Marcela.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Faz algum tempo que não "conversamos" aqui.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Vi o código que vc postou, e fiz uma implementação correspondente, sem usar os diversos delays que originalmente vc usou. Mas antes de falar sobre esta implementação, seguem algumas considerações:</span></p>
<p></p>
<p><span style="font-size: 12pt;"><strong><em> a)</em></strong> vc não informou qual placa <strong><em>Arduino</em></strong> está usando. Baseado nos seus tópicos anteriores, eu acredito que seja um <strong><em>ESP8266</em></strong> ou <strong><em>ESP32</em></strong>. Tranquilo, pois o código que implementei irá funcionar para ambos e também para as demais placas (<strong><em>UNO</em></strong>, <strong><em>Nano</em></strong>, <strong><em>Mega</em></strong>, <strong><em>STM32</em></strong>, etc).</span></p>
<p></p>
<p><span style="font-size: 12pt;"><strong><em> b)</em></strong> embora vc esteja usando <strong><em>LCD</em></strong> <strong><em>16x2</em></strong>, o código pode ser facilmente usado para LCDs com outras "dimensões" para colunas e linhas (se suportado pela Biblioteca utilizada para o LCD).</span></p>
<p></p>
<p><span style="font-size: 12pt;"><strong><em> c)</em></strong> no seu código original, vc exibiu textos no Display com uma "printagem" de caracter por caracter. Evite isso, porque sempre há como printar estes textos de forma "normal" ou seja, com o texto "completo" na linha de código. Da forma que vc fez, dificulta ver o que está sendo printado, e aumenta o código de uma forma desnecessária, além de ser extremamente mais trabalhoso. Além disso, vc printou os caracteres via <strong><em>código ASCII</em></strong> em decimal, o que não é necessário, pois bastaria usar o "<strong><em>write</em></strong>" com os caracteres entre apóstrofes, como neste exemplo: <strong><em>write('A')</em></strong> ao invés de <strong><em>write( byte(65) )</em></strong>. Ainda sobre isto, parece que vc usou o caracter ASCII de número "128" para printar um <strong><em>espaço em branco</em></strong>, o que está "incorreto". O caracter que vc deveria ter usado é o "<strong>32</strong>" (ou <strong><em>0x20</em></strong>, em Hexadecimal), que é o caracter ASCII oficial do "espaço em branco". Ocorre que o "128" poderá ser um caracter diferente do espaço em branco, dependendo do Controlador do Display usado na placa do módulo LCD.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Falando agora sobre as funcionalidades do seu código. Vc implementou três efeitos "animados" na exibição no Display. Vejamos quais são eles:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>1)</em></strong> efeito de exibição "<strong>gradual</strong>" do texto, <em><strong>caracter por caracter</strong></em>, com estes caracteres sendo printados em um intervalo de tempo especificado. E para isso vc printou cada caracter de forma sequencial no código, com uma função delay entre cada print para cadenciar a exibição do texto completo, e claro: isto causa seu código ficar preso nestas operações até que todo o texto seja printado.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>2)</em></strong> efeito de exibição "<strong>correndo</strong>" na linha do Display, <em>da direita para a esquerda</em>, com uma velocidade determinada por um intervalo de tempo entre cada printagem (em coluna anterior à que acabou de ser printada). Da mesma forma que no efeito anterior (o "gradual"), isto também causa seu código ficar preso nestas operações até que o texto seja printado na coluna final, pois vc também usou a função delay para cadenciar a sequência de prints.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>3)</em></strong> efeito "<strong>pisca/pisca</strong>" (ou "<strong>Blynk</strong>") do Display, com a visualização do mesmo "desligando" e "ligando" por intermédio das funções "lcd.noDisplay()" e "lcd.display()", executadas de forma intercalada em intervalos de tempo que determinam a velocidade do "pisca/pisca". E isto também prende a execução do seu código, até que sejam executados todos os ciclos do "pisca/pisca", entre os quais também estão funções delay.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Então implementei estes três efeitos ("<strong>gradual</strong>", "<strong>correndo</strong>", e "<strong>Blynk</strong>"), porém sem prender o código. Além disso para printar qualquer texto usando os efeitos, vc pode fazer isso especificando o texto completo, como no exemplo mostrado a seguir:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <span style="font-size: 10pt;"><strong><em>set_MSG_gradual_LINHA_n( linha_0, F("Marcela"), 0.25, 4.6 );</em></strong></span></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Neste exemplo, é requisitado que seja exibido na linha "0" do Display o texto "<strong><em>Marcela</em></strong>", de forma "<strong>gradual</strong>", ou seja, caracter por caracter, com intervalo de <strong><em>0.25 segundos</em></strong> (ou 250 mili-segundos). O tempo de exibição (mínimo) é de <strong><em>4.6 segundos</em></strong> a contar quando todo o texto está completo na linha. Também, o texto será <strong><em>automaticamente centralizado</em></strong> na linha (ou seja, vc não precisa ficar calculando a coluna inicial de acordo com comprimento do texto).</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Outro exemplo, neste caso com efeito "<strong><em>correndo</em></strong>":</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <span style="font-size: 10pt;"><strong><em>set_MSG_running_LINHA_n( linha_1, F("Robotica"), 0.2, 3.5 );</em></strong></span></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> onde o texto "<strong><em>Robotica</em></strong>" começa "<strong><em>correndo</em></strong>" na linha "1" da direita para a esquerda, com velocidade determinada pelo intervalo de <strong><em>0.2 segundos</em></strong>, até que o texto esteja centralizado na linha. O tempo de exibição (mínimo) é de <strong><em>3.5 segundos</em></strong>, a contar a partir do término do efeito "<strong><em>correndo</em></strong>".</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Exemplo de uso do efeito "<strong>Blynk</strong>" (ou "<strong><em>pisca/pisca</em></strong>") do Display:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <span style="font-size: 10pt;"><strong><em>set_Display_Blynk( 0.4, 3 );</em></strong></span></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Neste caso, o Display "pisca" na velocidade determinada pelo intervalo de tempo de <strong><em>0.4 segundos</em></strong>, sendo que no total serão <strong><em>3 piscadas</em></strong> (e ao final das piscadas, o Display fica sempre no "modo visível").</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Para cada efeito, foi implementa uma <strong><em>Máquina de Estados</em></strong> para gerenciamento do efeito. Para os efeitos "<strong><em>gradual</em></strong>" e "<strong><em>correndo</em></strong>" as Máquinas tem apenas 4 estados (sendo que um deles é apenas ficar esperando até que uma requisição de printagem seja feita). E a <strong><em>Máquina de Estados</em></strong> que faz o "<strong><em>Blynk</em></strong>" tem apenas 3 estados (onde um deles também é apenas ficar esperando).</span></p>
<p><span style="font-size: 12pt;"> Vc poderá implementar outros efeitos facilmente, se entender como estas Máquinas funcionam no código. Todas as três Máquinas implementadas funcionam do mesmo jeito, e qualquer outro efeito implementado também deverá funcionar do mesmo jeito.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Para que as Máquinas gerenciem corretamente os efeitos, vc <strong><em><u>NÃO</u></em></strong> deve "travar" o restante do seu código, ou seja, <em><u>não</u></em> use delays nem execute loops intermináveis ou de longa duração. Se vier a usar sensor <strong>DS18B20</strong>, use o modo de <strong><em>leitura</em></strong> "<strong><em>assíncrona</em></strong>" para impedir que o código fique longamente esperando uma resposta do Sensor. Se vc tiver alguma dificuldade com estas coisas, avise aqui para que eu possa te ajudar.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Vamos dar uma olha nas configurações básicas do código implementado, começando pela opção de escolha da <strong><em>Interface de Hardware</em></strong> usada para acesso ao <strong><em>módulo</em></strong> do <strong><em>Display LCD</em></strong>, conforme mostrado na figura a seguir:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p style="text-align: center;"><span style="font-size: 8pt;"><strong><em>(clique na figura para "zoom")</em></strong></span><span style="font-size: 12pt;"> <a href="https://storage.ning.com/topology/rest/1.0/file/get/9247106896?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9247106896?profile=RESIZE_710x" class="align-center" width="603" height="129"/></a></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Sim, vc pode escolher o tipo da Interface, entre a tradicional <strong><em>Interface Paralela</em></strong> de <strong><em>4 bits</em></strong>, e a concisa <strong><em>Interface I2C</em></strong> (que é a que vc está usando no seu código original). Na figura está selecionada a Interface I2C, conforme marcado na cor verde. Mude conforme seu Projeto.</span></p>
<p><span style="font-size: 12pt;"> E claro, se vc usar o <strong><em>I2C</em></strong>, deve especificar o <strong><em>endereço do módulo</em></strong> no <strong><em>Barramento</em></strong> <strong><em>I2C</em></strong>, conforme mostrado e marcado na cor laranja na figura a seguir:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p style="text-align: center;"><span style="font-size: 8pt;"><strong><em>(clique na figura para "zoom")</em></strong></span></p>
<p><span style="font-size: 12pt;"><a href="https://storage.ning.com/topology/rest/1.0/file/get/9247107867?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9247107867?profile=RESIZE_710x" class="align-center" width="570" height="162"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span><span style="font-size: 12pt;"> Para estas Interfaces, há outros <em>settings</em> que podem ser facilmente alterados no código (se selecionar a <strong><em>Interface Paralela</em></strong> de <strong><em>4 bits</em></strong>, certamente isso será necessário, para especificar os <strong><em>pinos</em></strong> do <strong><em>Arduino</em></strong> usados na Interface).</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A printagem dos textos, é feita em uma <strong><em>Máquina de Estados</em></strong> "<strong>principal</strong>", que é praticamente sequencial. Por motivos didáticos, esta Máquina "principal" é implementada dentro da função "<strong><em>loop</em></strong>" do <strong><em>Arduino</em></strong>. Para imprimir um texto, vc deve "requisitar" a operação desejada, pois esta operação será posteriormente executada por uma das <strong><em>Máquinas de Estados</em></strong> que implementam os efeitos no Display. Assim, há uma lógica simples a ser seguida para cada printagem de texto, e que se constitui de duas etapas:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em><u>Etapa 1</u></em></strong>: requisitar a printagem especificando o texto e parâmetros relacionados ao efeito.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em><u>Etapa 2</u></em></strong>: aguardar que a printagem seja concluída, chamando uma função que retorna "<em>true</em>" quando a operação de exibição terminar.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> E para cada uma destas etapas, implementa-se um estado na <strong><em>Máquina de Estados</em></strong> "<strong>principal</strong>". Para o código da Marcela, estes estados podem ser vistos na <strong><em>lista</em></strong> no trecho de código mostrado na figura a seguir:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p style="text-align: center;"><span style="font-size: 8pt;"><strong><em>(clique na figura para "zoom")</em></strong></span></p>
<p><span style="font-size: 12pt;"><a href="https://storage.ning.com/topology/rest/1.0/file/get/9247109464?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9247109464?profile=RESIZE_710x" class="align-center" width="600" height="458"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Cada cor na figura anterior (exceto as cores amarela e a roxa), corresponde a um processo de exibição no Display, onde nas linhas "0" e "1" do Display são exibidas informações relacionadas entre si. Exemplo: na região laranja é exibida de forma gradual na linha "0", o texto "Marcela", e logo em seguida é exibido "correndo" na linha "1" o texto "Automatização", e em seguida é feito um "pisca/pisca" no Display, e depois o Display é apagado (ou "limpo"). Cada um dos estados é executado, e após cada execução, segue para um dos estados marcados na área em amarelo do código, onde é esperado que seja concluída a exibição que foi requisitada. Ou seja, logo após executar o estado "<strong><em>Exibe_MSG_Marcela</em></strong>", é executado o estado "<strong><em>Aguarda_FIM_MSG_linha_0</em></strong>" (pois a printagem da mensagem foi na linha "0"). E então a execução segue para o estado "<strong><em>Exibe_MSG_Automatizacao</em></strong>" que printa na linha "1" e por isso segue para o estado "<strong><em>Aguarda_FIM_MSG_linha_1</em></strong>", seguindo para o estado "<strong><em>Pisca_MSG_Automatizacao</em></strong>", e assim por diante.</span></p>
<p><span style="font-size: 12pt;"> Se em um determinado estado forem exibidas mensagens em ambas as linhas do Display, então o estado seguinte deve ser o "<strong><em>Aguarda_FIM_MSG_Display</em></strong>" que aguarda o fim das exibições em todas as linhas do Display.</span></p>
<p><span style="font-size: 12pt;"> Em suma, a sequência de execução dos estados é sempre printando no Display, e então aguardando que a operação de printagem termine (estados na área marcada em amarelo).</span></p>
<p><span style="font-size: 12pt;"> O estado marcado na cor roxa, simplesmente aguarda um período de tempo (para isso ele printa uma mensagem "vazia" que demora o tempo desejado), e então reinicia todo o processo a partir do primeiro estado (neste caso o "<strong><em>Exibe_MSG_Bem_vindo</em></strong>", marcado em azul na figura anterior).</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Notar que printagens sem efeitos de animação do texto, são feitas especificando-se um intervalo de tempo nulo (igual a zero) na determinação da velocidade da animação do texto. É isso que é feito nos estados "<strong><em>Exibe_MSG_Bem_vindo</em></strong>" e "<strong><em>Exibe_MSG_Casa_Robotica</em></strong>", ambos na área marcada em azul na figura anterior.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A princípio, o processo pode parecer complexo, mas na realidade é simples, como pode ser visto na figura a seguir que mostra toda a <strong><em>Máquina de Estados</em></strong> "<strong>principal</strong>" sendo executada dentro do "<strong><em>loop</em></strong>" do <strong><em>Arduino</em></strong>:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p style="text-align: center;"><span style="font-size: 8pt;"><strong><em>(clique na figura para "zoom")</em></strong></span></p>
<p><span style="font-size: 12pt;"><a href="https://storage.ning.com/topology/rest/1.0/file/get/9247113292?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9247113292?profile=RESIZE_710x" class="align-center" width="662" height="1801"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Notar que os estados estão marcados individualmente para facilitar a identificação dos mesmos, e que a cor da marcação correspondem às mesmas cores usadas na figura que mostrou a definição destes estados. Observar que nos estados de printagem de mensagens, as operações são simples e seguem <em><u>sempre</u></em> o mesmo padrão. Da mesma forma, nas áreas marcadas em amarelo, que são os estados que esperam a conclusão das operações de printagem, também são muito simples e também seguem um padrão.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em><u>Importante</u></em></strong>: se forem acrescentados mais estados de printagem no Display, os estados nas áreas em amarelo permanecem os mesmos, pois já contemplam todas as possibilidades de aguardar a conclusão das operações implementadas neste Sistema (printagem na linha "0", na linha "1", em ambas as linhas, e "pisca/pisca").</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>Então como criar um estado de printagem?</em></strong> <u>Simples</u>: dê um <strong><em>nome</em></strong> ao estado, e então acrescente este nome à <strong><em>lista</em></strong> onde está a definição dos estados (pode ser em qualquer ordem na lista, mas tente manter uma organização lógica pra seu próprio benefício). Então, na <strong><em>Máquina de Estados</em></strong> "<strong>principal</strong>", acrescente a execução do estado seguindo o <strong><em>mesmo padrão</em></strong> usado para aqueles já implementados (acrescente a execução do estado conforme a ordem que vc deseja que seja executado dentro da <strong><em>Máquina de Estados</em></strong>). Dentro do estado, <em><u>não</u></em> "invente" nenhuma lógica maluca (principalmente usando loops). Claro, também <em><u>não</u></em> devem ser usados <strong><em>delays</em></strong> <strong><em>convencionais</em></strong> dentro dos estados.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> É possível tornar ainda mais simples todo o mecanismo de exibição das mensagens. Por exemplo, sem precisar usar os estados para verificar se a exibição foi concluída (estados nas áreas em amarelo). Mas isto requer um pouco mais de memória <strong>RAM</strong>, e como esta memória é preciosa em alguns <strong><em>Arduinos</em></strong> (como <strong><em>UNO</em></strong>, <strong><em>Nano</em></strong>, etc), não fiz esta implementação para esta versão do código, para garantir que haja no Sistema <strong>RAM</strong> suficiente para uso com outros dispositivos e suas respectivas estruturas de dados.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Para a demonstração do funcionamento dos efeitos, implementei <strong><em>Simulações</em></strong> no <strong><em>Proteus</em></strong> usando os dois tipos de Interface para o LCD, ou seja, <strong><em>Paralela</em></strong> e <strong><em>I2C</em></strong>. Isto foi feito para com <strong><em>Arduino UNO</em></strong>, mas pode ser usado qualquer outro <strong><em>Arduino</em></strong> que esteja disponível no <strong><em>Proteus</em></strong>. O circuito para a <strong><em>Interface I2C</em></strong> é mostrado na figura a seguir:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p style="text-align: center;"><span style="font-size: 8pt;"><strong><em>(clique na figura para "zoom")</em></strong></span></p>
<p><span style="font-size: 12pt;"><strong><em><a href="https://storage.ning.com/topology/rest/1.0/file/get/9247117664?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9247117664?profile=RESIZE_710x" class="align-center" width="504" height="407"/></a> </em></strong></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span><span style="font-size: 12pt;"> E para a <strong><em>Interface Paralela</em></strong> de <strong><em>4 bits</em></strong>, mostrado na figura a seguir:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p style="text-align: center;"><span style="font-size: 8pt;"><strong><em>(clique na figura para "zoom")</em></strong></span></p>
<p><span style="font-size: 12pt;"><a href="https://storage.ning.com/topology/rest/1.0/file/get/9247117883?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9247117883?profile=RESIZE_710x" class="align-center" width="414" height="369"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Também capturei estas Simulações em vídeo, e elas podem ser vistas nos links a seguir, onde é possível também fazer o download dos vídeos:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Vídeo da Simulação com Interface I2C: <a rel="nofollow noopener" href="https://1drv.ms/v/s!Amu91_NWVNMvhQSic-lFnuClbXkZ?e=JviO1w" target="_blank">"<span style="text-decoration: underline;"><strong><em>simul LCD I2C</em></strong></span>"</a></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Vídeo da Simulação com Interface Paralela: <a rel="nofollow noopener" href="https://1drv.ms/v/s!Amu91_NWVNMvhQM_po1-QaAcS3jP?e=u0CeYc" target="_blank">"<span style="text-decoration: underline;"><strong><em>simul LCD Paralelo</em></strong></span>"</a></span></p>
<p></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Notar que as Simulações feitas, seguem o código original da Marcela, que tem intervalos de tempo de 5 segundos entre algumas etapas de exibição no Display e por isso mesmo em alguns momentos parece que nada está ocorrendo. E claro: lembrar que as Simulações ocorrem em um tempo "virtual" que é sempre mais lento que o tempo real, principalmente no caso da versão com <strong><em>Interface I2C</em></strong>.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> O código implementado está neste link: <a href="https://storage.ning.com/topology/rest/1.0/file/get/9247118492?profile=original" target="_blank" rel="noopener">"<span style="text-decoration: underline; font-size: 10pt;"><em><strong>LCD_16_x_2_Views_02.zip</strong></em></span>"</a></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> E os arquivos para <strong><em>Simulação</em></strong> no <strong><em>Proteus</em></strong> estão aqui: <a href="https://storage.ning.com/topology/rest/1.0/file/get/9247119073?profile=original" target="_blank" rel="noopener">"<span style="text-decoration: underline; font-size: 10pt;"><em><strong>Simulacao_Proteus.zip</strong></em></span>"</a></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Qualquer dúvida, não deixe de perguntar.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Espero ter ajudado.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Abrçs,</span></p>
<p><span style="font-size: 12pt;"> Elcids</span></p> Boa tarde, tudo bem?
O milli…tag:labdegaragem.com,2021-07-12:6223006:Comment:8713222021-07-12T17:04:13.761ZCurti Esse Lado Seu Otimistahttps://labdegaragem.com/profile/eijuito
<p>Boa tarde, tudo bem?</p>
<p></p>
<p>O millis() funciona de forma diferente do daley() e acho que está bem explicado pelo nosso amigo e mestre Mr TM.</p>
<p></p>
<p>Se quiser, tenho uma biblioteca que criei para realizar tarefas concorrentes e mostrar textos em display LCD que você poderá usar como exemplo ou aproveitar as idéias.</p>
<p></p>
<p>Nesta biblioteca, resolvi muitas questões além do uso (e abuso) do millis(), tem também a economia de memória nos textos do display, chamada de…</p>
<p>Boa tarde, tudo bem?</p>
<p></p>
<p>O millis() funciona de forma diferente do daley() e acho que está bem explicado pelo nosso amigo e mestre Mr TM.</p>
<p></p>
<p>Se quiser, tenho uma biblioteca que criei para realizar tarefas concorrentes e mostrar textos em display LCD que você poderá usar como exemplo ou aproveitar as idéias.</p>
<p></p>
<p>Nesta biblioteca, resolvi muitas questões além do uso (e abuso) do millis(), tem também a economia de memória nos textos do display, chamada de funções callback automáticas ou manual, entre outras coisinhas que implementei.</p>
<p></p>
<p><a href="https://github.com/eijuito/IToSmartMenu" target="_blank">https://github.com/eijuito/IToSmartMenu</a></p>
<p></p>
<p>Aproveite e boa sorte!!!</p>
<p> 'Eiju</p> Olá Marcela de Souza. Tudo be…tag:labdegaragem.com,2021-07-11:6223006:Comment:8712702021-07-11T00:55:39.107Ztiago merceshttps://labdegaragem.com/profile/tiagomerces
<p>Olá Marcela de Souza. Tudo bem?</p>
<p></p>
<p></p>
<p><strong>"...na apresentação do lcd meu código fica travado ate a execução" </strong></p>
<p></p>
<p>"Execução" de que? Seu código está bem objetivo e está sempre executando algo.</p>
<p></p>
<p>Em todo caso, vamos revisar um pouco do temporizador com millis()?…</p>
<p></p>
<p></p>
<p>Olá Marcela de Souza. Tudo bem?</p>
<p></p>
<p></p>
<p><strong>"...na apresentação do lcd meu código fica travado ate a execução" </strong></p>
<p></p>
<p>"Execução" de que? Seu código está bem objetivo e está sempre executando algo.</p>
<p></p>
<p>Em todo caso, vamos revisar um pouco do temporizador com millis()?</p>
<p></p>
<p><a href="https://www.arduino.cc/reference/pt/language/functions/time/millis/" target="_blank">https://www.arduino.cc/reference/pt/language/functions/time/millis/</a></p>
<p></p>
<p>millis() é uma função que retorna o valor, em milissegundos, desde que a placa foi iniciada. ok?</p>
<p>Isto é, se você ligou a placa agora, e em 10 segundos (exatos e precisos) você bater um "millis()", ele irá retornar 10.000. </p>
<p></p>
<p><strong>=== Pausa 1) Tudo bem até aqui? ===</strong></p>
<p></p>
<p>Quando queremos criar um "delay" com millis(), inicialmente teremos que entender como gerar uma subtração de uma variável qualquer com o millis().</p>
<p></p>
<p>Exemplo:</p>
<p>se iniciou a placa, a EXATOS (teóricos) 10 segundos, e queremos o valor dela, menos 1 segundo, teremos:</p>
<p></p>
<p>int var = 1000; // que pode ser entendido como 1000 ms ou 1s.</p>
<p></p>
<p>millis() - var ===> 10.000 - 1.000 ===> 9.000.</p>
<p></p>
<p></p>
<p><strong>=== PAUSA 2) Tudo bem até aqui? ===</strong></p>
<p></p>
<p>Só que, para gerar um "delay", essa variável precisa ter um valor mais preciso. concorda? </p>
<p>Se queremos 1 seg de "delay", e tendo em vista que nosso "millis()" está em 10seg, nosso "var" deveria ser 9.000.</p>
<p>Assim, 10.000 - 9.000 = 1.000.</p>
<p></p>
<p><strong>=== PAUSA 3) Tudo bem até aqui? ===</strong></p>
<p></p>
<p>Sendo assim, devemos criar uma nova variável para que possamos captar o valor de millis(). Vamos chamar essa variável de VARmillis.</p>
<p></p>
<p>E agora veja este exemplo:</p>
<p></p>
<p></p>
<p>// Declaramos as 2 variáveis que serão usadas</p>
<p></p>
<p>unsigned long VARmillis; // Variável responsável por armazenar o valor do momento "X" de millis()</p>
<p>int VARdelay = 1000; // definimos um tempo para o delay</p>
<p></p>
<p>setup() {</p>
<p>VARmillis = millis(); // Aqui definimos o valor de VARmillis sendo IGUAL ao de millis()</p>
<p>// exemplo: millis() == 00100, VARmillis == 00100</p>
<p>}</p>
<p></p>
<p>// Observe que quando o código CHEGA nesta linha, o valor de VARmillis não será mais igual ao de millis().</p>
<p>// Isto é, millis() == 00101, VARmillis == 00100.</p>
<p>// Percebe, só nisso, que já podemos obter uma diferença entre valores? neste caso, 101 - 100 = 1</p>
<p>// Então, como nosso objetivo é o delay, queremos que esse "1" seja igual a "1000". Correto?</p>
<p>// então daremos continuidade</p>
<p></p>
<p>loop(){</p>
<p>if (<strong>millis() - VARmillis == VARdelay</strong>){</p>
<p>// aqui acontecerá a ação, se isto for verdadeiro</p>
<p>}</p>
<p></p>
<p>Como definimos VARdelay == 1000, então a ação só irá acontecer SE, e tão somente SE, a diferença entre millis() e VARmillis for EXATAMENTE igual a VARdelay.</p>
<p></p>
<p><em>"Olha que legal!"</em></p>
<p></p>
<p></p>
<p></p>
<p><strong>== PAUSA 4) Tudo bem até aqui? ==</strong></p>
<p></p>
<p>Então, nesta situação do loop, observe que o delay só irá acontecer <strong>UMA UNICA VEZ. </strong>Então vamos entender como isso funciona?</p>
<p></p>
<p>A questão agora é puramente lógica de programação.</p>
<p></p>
<p></p>
<p>Situação 1:</p>
<p></p>
<p>loop(){</p>
<p>if (<strong>millis() - VARmillis == VARdelay</strong>){</p>
<p>// Irá acontecer SOMENTE se millis() - VARmillis for IGUAL a Vardelay</p>
<p>// isso só acontece 1 vez, pois, millis() representa o tempo, e o tempo "nunca" volta.</p>
<p>}</p>
<p></p>
<p>Situação 2:</p>
<p></p>
<p>loop(){</p>
<p>if (<strong>millis() - VARmillis < VARdelay</strong>){</p>
<p>// Irá acontecer SOMENTE se millis() - VARmillis for MENOR a VARdelay</p>
<p>// observe que neste cenário, isso irá gerar um loop e só irá PARAR quando o valor de VARdelay for IGUAL ou MAIOR que a subtração de millis() por VARmillis.</p>
<p>}</p>
<p></p>
<p>Situação 3:</p>
<p></p>
<p>loop(){</p>
<p>if (<strong>millis() - VARmillis > VARdelay</strong>){</p>
<p>// Irá acontecer SOMENTE se millis() - VARmillis for MAIOR que VARrdelay</p>
<p>// Ou seja, enquanto VARdelay for menor ou igual, o evento não irá acontecer, entretanto, quando for maior, ele irá retornar sempre verdadeiro, então o evento se repetirá "infinitamente".</p>
<p>}</p>
<p></p>
<p><strong>=== PAUSA 5) Tudo bem até aqui? ===</strong></p>
<p></p>
<p>Situação 4:</p>
<p></p>
<p>loop(){</p>
<p>if (<strong>millis() - VARmillis == VARdelay</strong>)</p>
<p>{</p>
<p></p>
<p>// Irá acontecer SOMENTE se millis() - VARmillis for IGUAL a VARdelay</p>
<p>// isso só acontece 1 vez, pois, millis() representa o tempo, e o tempo "nunca" volta.</p>
<p></p>
<p><span style="text-decoration: underline;"><strong>VARmillis = millis()</strong></span><strong> </strong>// Isso irá definir um NOVO valor para VARmillis.</p>
<p>}</p>
<p></p>
<p>Opa! para tudo! Se VARmillis terá o valor igual ao de millis(), o que isso significa? UM RESET!!!</p>
<p>Ou seja, a cada 1 segundo, esta ação irá acontecer.</p>
<p></p>
<p>Então, percebe que sempre que a gente quer reiniciar a condição que gera o atraso, bastará atribuir o valor de VARmillis ao novo valor de millis()!!!</p>
<p></p>
<p>Que legal em? </p>
<p></p>
<p></p>
<p><strong>=== PAUSA 6) Tudo bem até aqui? ===</strong></p>
<p></p>
<p>Então chegamos ao ponto importante. O que nós desejamos? de todas as situações apresentadas, o que será melhor para o nosso código? Ai é necessário que cada um diga por si.</p>
<p></p>
<p>Existem várias formas de se utilizar o millis(), mas essas são as mais populares.</p>
<p></p>
<p></p>