Controle de Display de 7 segmentos (arduino) - Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)2024-03-28T22:26:38Zhttps://labdegaragem.com/forum/topics/controle-de-display-de-7-segmentos-arduino?xg_source=activity&feed=yes&xn_auth=no(continuação do post anterio…tag:labdegaragem.com,2021-07-15:6223006:Comment:8713572021-07-15T15:54:31.348ZElcids Chagashttps://labdegaragem.com/profile/ElcidsChagas
<p></p>
<p style="text-align: center;"><span style="font-size: 12pt;"><em>(continuação do post anterior, iniciado neste <span style="text-decoration: underline;"><a href="https://labdegaragem.com/forum/topics/controle-de-display-de-7-segmentos-arduino?commentId=6223006%3AComment%3A871436" rel="nofollow noopener" target="_blank">Link</a></span>)</em></span></p>
<p></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Vejamos agora alguns detalhes a respeito…</span></p>
<p></p>
<p style="text-align: center;"><span style="font-size: 12pt;"><em>(continuação do post anterior, iniciado neste <span style="text-decoration: underline;"><a rel="nofollow noopener" href="https://labdegaragem.com/forum/topics/controle-de-display-de-7-segmentos-arduino?commentId=6223006%3AComment%3A871436" target="_blank">Link</a></span>)</em></span></p>
<p></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Vejamos agora alguns detalhes a respeito da <strong><em>Interrupção</em></strong> usada para fazer a varredura dos Displays e dos Botões. Esta <strong><em>ISR</em></strong> ("<strong>Interrupt Service Routine</strong>" = <strong><em>Rotina de Serviço da Interrupção</em></strong>), é gerada pelo <strong><em>TIMER1</em></strong>, que é programado logo no início da execução do código, para gerar uma <strong><em>IRQ</em></strong> ("<strong>Interrupt Request</strong>" = <strong><em>Requisição de Interrupção</em></strong>) <strong><em>150 vezes por segundo</em></strong> (ou a cada <strong><em>6.67</em></strong> <strong><em>mili-segundos</em></strong>). Uma observação: o <strong><em>TIMER1</em></strong> do Processador do UNO, tem 4 fontes de Interrupção diferentes, e destas 4 fontes 3 poderiam ser utilizadas para gerar as IRQs para cadenciar a varredura do Display, mas neste Sistema estamos usando a Interrupção gerada pelo <strong><em>COMPA</em></strong> ("<strong><em>Compare Match A</em></strong>").</span></p>
<p><span style="font-size: 12pt;"> A programação do <strong><em>TIMER1</em></strong> para gerar as IRQs é feita na função "<strong>config_Display_Refresh</strong>", e embora esta seja extremamente simples, também é muito específica já que programa o Hardware do <strong><em>TIMER1</em></strong>, e por isso não irei falar sobre ela aqui (o código está funcionalmente comentado e descreve as operações realizadas). Mas caso alguém tenha alguma dúvida, pergunte aqui mesmo neste tópico.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A <strong><em>ISR</em></strong> do "<strong>TIMER1 COMPA</strong>" é mostrada 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/9253789486?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253789486?profile=RESIZE_710x" width="431" height="361" class="align-center"/></a></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Esta <strong><em>ISR</em></strong> tem três etapas:</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>1)</em></strong> <strong><em>atualizar</em></strong> o Display, executando assim a varredura do mesmo, que é a área marcada na <strong><em>cor verde</em></strong> na figura anterior. Para isto é usada a <strong><em>variável local</em></strong> "<strong>DISPLAY_sel</strong>" (que é do tipo "<strong>static</strong>", e portanto retém seu valor mesmo depois que a rotina termina sua execução), a qual indica qual Display será "ligado" neste momento (e por <strong><em>6.67ms</em></strong> quando a próxima <strong><em>IRQ</em></strong> ocorrer). Quando a <strong><em>ISR</em></strong> é executada pela primeira vez (e apenas na primeira vez!), "<strong>DISPLAY_sel</strong>" estará com o valor "<strong>1</strong>", indicando que o <strong><em>Display</em></strong> "<strong>1</strong>" será "ligado" e exibirá o valor correspondente ao mesmo. Então conforme cada statement "<strong>case</strong>" do "<strong>switch</strong>" é chamada a função "<strong>set_Digito_Display</strong>" passando como parâmetros a variável correspondente ao Display atualmente sendo "ligado" (ou "<strong>SENHA_IN_1</strong>", ou "<strong>SENHA_IN_2</strong>", ou "<strong>SENHA_IN_3</strong>"), e também o número correspondente ao Display (ou "<strong>1</strong>", ou "<strong>2</strong>", ou "<strong>3</strong>"). Assim esta função "<strong>set_Digito_Display</strong>" irá setar nos pinos correspondentes aos bits "<strong>A</strong>", "<strong>B</strong>", "<strong>C</strong>", e "<strong>D</strong>" do <strong><em>Decoder 4511</em></strong>, o <strong><em>valor binário</em></strong> correspondente ao valor a ser exibido (dado por "<strong>SENHA_IN_1</strong>", "<strong>SENHA_IN_2</strong>", ou "<strong>SENHA_IN_3</strong>"), mantendo ligado apenas o Display especificado ("<strong>1</strong>", "<strong>2</strong>", ou "<strong>3</strong>"), e deixando desligado os demais. Mais à frente veremos como a função "<strong>set_Digito_Display</strong>" faz isso.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>2)</em></strong> <strong><em>selecionar</em></strong> o Display que será "ligado" na próxima execução da <strong><em>ISR</em></strong> (que ocorrerá daqui a <strong><em>6.67ms</em></strong>), que é a área marcada na <strong><em>cor azul</em></strong> na figura anterior. Para isso, simplesmente é incrementada a variável "<strong>DISPLAY_sel</strong>". Mas como esta variável deve ir de <strong><em>1</em></strong> a <strong><em>3</em></strong>, se o incremento ultrapassar "<strong>3</strong>", então a variável é reciclada para o valor "<strong>1</strong>", assim selecionando o <strong><em>Display</em></strong> "<strong>1</strong>" para a <em>próxima</em> <strong><em>IRQ</em></strong>.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>3)</em></strong> <strong><em>executar</em></strong> o "<strong>HOOK</strong>" correspondente a esta <strong><em>ISR</em></strong>, que é a área marcada na <strong><em>cor amarela</em></strong> na figura anterior. Um "<strong>HOOK</strong>" nada mais é do que uma chamada a uma função "genérica", e esta função pode ser alterada a qualquer momento pelo código que controla o Sistema. No entanto, neste Sistema este "<strong>HOOK</strong>" é setado uma única vez, logo no início da execução do código, para apontar a função "<strong>atualiza_Status_Botoes</strong>", e assim mantido durante todo o funcionamento do Sistema (ou seja, o "<strong>HOOK</strong>" não é mais alterado). Portanto, na área marcada na cor amarela, simplesmente será chamada a função "<strong>atualiza_Status_Botoes</strong>", a qual fará a <strong><em>varredura dos Botões</em></strong> e atualizará os status dos mesmos. A função que seta este "<strong>HOOK</strong>" é a "<strong>config_Botoes</strong>", que já foi mostrada quando falamos sobre a configuração dos Botões. Todas estas funções são extremamente simples e estão muito organizadas, então vale a pena vc dar uma olhada nas mesmas, pois certamente o aprendizado será significativo.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Então após a execução destas 3 etapas, a <strong><em>ISR</em></strong> termina, e o Processador volta a executar o código "normal" no "<strong>foreground</strong>". A <strong><em>ISR</em></strong> será executada repetidamente, a cada <strong><em>6.67ms</em></strong>, onde o próximo Display será ligado para exibir seu valor correspondente, e também será feita a <strong><em>varredura dos Botões</em></strong> para a atualização dos status dos mesmos.</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 olhada rápida na função "<strong><em>set_Digito_Display</em></strong>", a qual recebe como parâmetros o valor a ser exibido num dos Displays e o indicador de qual é este Display. Esta função pode ser vista 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/9253807653?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253807653?profile=RESIZE_710x" class="align-center" width="416" height="563"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> O valor a ser exibido é especificado através do <strong><em>parâmetro</em></strong> "<strong>DIGITO_N</strong>", o qual deve estar entre "<strong>0</strong>" e "<strong>9</strong>", uma vez que corresponde a um Dígito da Senha. Por este motivo, o Display só será atualizado se o valor do Dígito estiver dentro da faixa correta (menor ou igual a "<strong>9</strong>"), o que pode ser constatado no statement "<strong>if</strong>" na <strong><em>linha 541</em></strong> na figura anterior.</span></p>
<p><span style="font-size: 12pt;"> Mas antes disso, temos a execução da função "<strong>set_Display_OFF</strong>", cujo objetivo é desligar todos os Displays, o que é feito através dos pinos que controlam os <strong><em>Transistores</em></strong> <strong><em>Q1</em></strong>, <strong><em>Q2</em></strong>, e <strong><em>Q3</em></strong>. A função "<strong>set_Display_OFF</strong>" é extremamente simples e pode ser vista 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/9253807695?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253807695?profile=RESIZE_710x" class="align-center" width="449" height="147"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Então no início da função "<strong>set_Digito_Display</strong>" temos que todos os três Displays são desligados. Portanto se o valor do "<strong>DIGITO_N</strong>" estiver fora da faixa permissível, como resultado temos que todos os Displays desligam, o que de certa forma nos sinaliza que alguma coisa está errada no código. Isto pode ser entendido quase como um teste de sanidade. Em outras palavras, o teste "<strong>if</strong>" pode ser eliminado, desde que seu código mantenha os valores dos Dígitos dentro da faixa correta. Mas a boa prática de programação, aconselha que se mantenha o teste "<strong>if</strong>" da <strong><em>linha 541</em></strong>.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Na figura que mostra a função "<strong>set_Digito_Display</strong>", existem 4 áreas marcadas na <strong><em>cor verde</em></strong>. Cada uma dessas 4 áreas, testa um bit do valor "<strong>DIGITO_N</strong>", e reproduz esse bit nos pinos "<strong>A</strong>" a "<strong>D</strong>" do <strong><em>Decoder 4511</em></strong>. Dessa forma, o valor do "<strong><em>DIGITO_N</em></strong>" será traduzido pelo <strong><em>Decoder 4511</em></strong>, para seu equivalente em <strong><em>7 segmentos</em></strong>. O teste para saber se cada bit está em "<strong>0</strong>" ou "<strong>1</strong>" é feito através da operação <strong><em>AND</em></strong> (o "<strong>&</strong>" da <strong><em>Linguagem C/C++</em></strong>) com os valores <strong><em>0x01</em></strong> (para teste do <strong><em>bit</em></strong> "<strong>0</strong>"), <strong><em>0x02</em></strong> (teste do <strong><em>bit</em></strong> "<strong>1</strong>"), <strong><em>0x04</em></strong> (teste do <strong><em>bit</em></strong> "<strong>2</strong>"), e finalmente <strong><em>0x08</em></strong> (teste do <strong><em>bit</em></strong> "<strong>3</strong>"). Então conforme o resultado destes testes, ou "<strong>HIGH</strong>" ou "<strong>LOW</strong>" será setado nos pinos "<strong>A</strong>" a "<strong>D</strong>" do <strong><em>4511</em></strong>. Ou seja, a reprodução direta e simples de um valor binário de 4 bits.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Mas em qual dos Displays este valor aparecerá? Isto é dado pelo <strong><em>parâmetro</em></strong> "<strong>DISPLAY_select</strong>", que especifica a qual dos Displays corresponde o valor "<strong>DIGITO_N</strong>". Logo o parâmetro "<strong>DISPLAY_select</strong>" pode assumir valores de <strong>1</strong> a <strong>3</strong>, indicando assim em qual Display "aparecerá" o valor decodificado pelo <strong><em>4511</em></strong>. Dentro do statement "<strong>switch</strong>" (na <strong><em>linha 575</em></strong>), há 3 áreas marcadas na <strong><em>cor azul</em></strong>, e cada uma testa se "<strong>DISPLAY_select</strong>" é um dos três Displays. Como se vê pela lógica extremamente simples, somente o Display especificado pelo parâmetro "<strong>DISPLAY_select</strong>" será ligado. E a função termina.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> E o processo de varredura continua indefinidamente, na <strong><em>taxa</em></strong> de <strong><em>150 Hz</em></strong>.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Aqui, para não demorar mais, não irei falar sobre detalhes da leitura/processamento dos <strong><em>status dos Botões</em></strong> (embora a lógica ainda seja simples). Mas qualquer dúvida é só perguntar.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Mas há um ponto muito importante a verificar. Quanto tempo todas as operações executadas na <strong><em>ISR</em></strong>, levam para serem executadas??? A forma mais simples de verificar isso é medindo. Então o que eu fiz foi usar um pino "sobrando" no UNO para gerar um <strong><em>pulso digital</em></strong> que corresponda à praticamente o <strong><em>tempo de duração</em></strong> da <strong><em>ISR</em></strong>. No caso, usei o pino 8, embora isso não apareça no circuito nem no código, pois fiz isso em uma cópia do Projeto apenas para a medição. Simplesmente, a primeira coisa que é feita na <strong><em>ISR</em></strong>, é setar o pino 8 em "HIGH", e a última coisa feita na ISR é setar o pino em "LOW". Isto fornece excelente precisão na medição do tempo gasto na <strong><em>ISR</em></strong>. O resultado pode ser visto na figura a seguir, capturada do <strong><em>Osciloscópio</em></strong> "<strong>virtual</strong>" do <strong><em>Proteus</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/9253808465?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253808465?profile=RESIZE_710x" class="align-center" width="413" height="271"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Como se vê na figura anterior, são gastos cerca de <strong><em>80 µs</em></strong> na <strong><em>ISR</em></strong>, e isto inclui a varredura do Display e dos três Botões. E qual percentual este tempo corresponde em relação ao tempo que sobra para a execução do código "normal" (no "foreground")??? Simples: basta dividir <strong><em>80µs</em></strong> por <strong><em>6.67ms</em></strong> (o <strong><em>ciclo</em></strong> da <strong><em>ISR</em></strong> <strong><em>= 1 / 150Hz</em></strong>), e então multiplicar por 100%, e teremos o percentual desejado. Vejamos então: <strong><em>80µs / 6.67ms = 0.012</em></strong>, e o percentual será <strong><em>100% x 0.012 = 1.2%</em></strong>. Ou seja, arredondando temos que <em><u>todo</u></em> o <strong><em>processamento da ISR</em></strong> corresponde a cerca de <strong><em>1%</em></strong> do <strong><em>processamento total do Sistema</em></strong>. A coisa então é muito eficiente (mas como eu disse no início do post, algum cuidado especial deve ser tomado se forem acrescentados ao Sistema dispositivos "<strong>OneWire</strong>" ou semelhantes a <strong><em>DHT11</em></strong> ou <strong><em>DHT22</em></strong>").</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Aproveitando, pode-se verificar o <strong><em>ciclo da ISR</em></strong>, bastando apenas ajustar a <strong><em>escala de tempo</em></strong> do <strong><em>Osciloscópio</em></strong> "<strong>virtual</strong>" do <strong><em>Proteus</em></strong>, conforme pode ser visto 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/9253813460?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253813460?profile=RESIZE_710x" class="align-center" width="420" height="276"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> E conforme esperado, o ciclo é de <strong><em>6.67ms</em></strong>, correspondente aos <strong><em>150 Hz</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;"> <span style="text-decoration: underline; font-size: 14pt;"><strong><em>Sobre a inicialização do Sistema</em></strong></span></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Dado ao objetivo deste tópico, não há muito para falar sobre a inicialização do Sistema. Mas qualquer dúvida sobre este processo, basta perguntar. Vejamos a função "<strong><em>setup</em></strong>" do <strong><em>Arduino</em></strong>, que é obrigatória nesta Plataforma, e é mostrada 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/9253817279?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253817279?profile=RESIZE_710x" class="align-center" width="435" height="134"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Ali, há apenas três funções de inicialização sendo executadas.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A primeira é a "<strong>config_LEDs</strong>", que simplesmente configura como saídas, os pinos dos LEDs "<strong>OK</strong>" e "<strong>ERRO</strong>", e também garante que inicialmente estes LEDs estejam desligados.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A segunda é a "<strong>config_Botoes</strong>", já mostrada aqui no post. Ela configura como entradas, os pinos dos Botões, e inicializa os status de cada Botão. Também nesta função, como já dito, é setado o "<strong>HOOK</strong>" existente na <strong><em>ISR</em></strong> do "<strong>TIMER1 COMPA</strong>" para que seja feita a <strong><em>varredura dos Botões</em></strong> e atualização dos status dos mesmos (via função "<strong>atualiza_Status_Botoes</strong>"). Observar que, o "<strong>HOOK</strong>" só será executado após a configuração do <strong>TIMER1</strong>, o que é feito logo a seguir.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A terceira e última função no "<strong><em>setup</em></strong>", é a "<strong>init_Display_Control</strong>". Ela primeiro configura e inicializa todos os pinos relacionados com o controle dos Displays (os pinos conectados ao <strong><em>Decoder 4511</em></strong> e os de <strong><em>ON/OFF</em></strong> dos Displays via <strong><em>Transistores</em></strong> <strong><em>Q1</em></strong> a <strong><em>Q3</em></strong> do circuito). Então ela configura o <strong><em>TIMER1</em></strong> para gerar as Interrupções que cadenciam a varredura dos Displays na taxa de <strong><em>150Hz</em></strong> (incluindo a execução do "<strong>HOOK</strong>" para tratamento dos Botões).</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <span style="text-decoration: underline; font-size: 14pt;"><strong><em>Sobre a entrada e verificação da Senha</em></strong></span></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A inserção (ou entrada) da <strong><em>Senha</em></strong>, é controlada através de uma <strong><em>Máquina de Estados</em></strong>, e somente <strong><em>3 estados</em></strong> foram necessários para todo o controle.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Mas antes de falar sobre a execução desta Máquina, vamos ver duas funções muito simples, que são utilizadas para <strong><em>decrementar</em></strong> ou <strong><em>incrementar</em></strong> os valores dos dígitos da Senha quando a mesma está sendo "inserida" via <strong><em>Botões</em></strong> "<strong>1</strong>" e "<strong>2</strong>". Também veremos a função que verifica se a Senha inserida está correta. Estas funções são mostradas 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/9253818280?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253818280?profile=RESIZE_710x" class="align-center" width="484" height="483"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A primeira função, de nome "<strong>decrementa_Digito_Senha</strong>", irá decrementar o valor do <strong><em>parâmetro</em></strong> "<strong>valor_DIGITO</strong>". Notar que o valor é do tipo byte, sendo que o "<strong>&</strong>" logo após a palavra "byte" indica que o parâmetro é passado para a função "<em><u>por referência</u></em>", ou seja, a função irá alterar a variável original correspondente ao parâmetro fornecido. O funcionamento é muito simples: a função verifica se o valor é "<strong>0</strong>", e caso seja, ele é setado para "<strong>9</strong>", já que a faixa de valores deve ir de <strong>0</strong> a <strong>9</strong>. Mas se o valor for outro, ele simplesmente é <strong><em>decrementado</em></strong>.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A segunda função, de nome "<strong>incrementa_Digito_Senha</strong>", tem o mesmo mecanismo, porém irá incrementar o <strong><em>parâmetro</em></strong> <strong>"valor_DIGITO</strong>", também fornecido "<em><u>por referência</u></em>". Mas aqui é verificado se o valor é "<strong>9</strong>", e caso seja, ele é setado em "<strong>0</strong>". Do contrário, o valor é simplesmente <strong><em>incrementado</em></strong>.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A terceira e última função, a "<strong>verifica_SENHA</strong>", verifica se está correta a Senha atualmente inserida. Como a Senha inserida é constituída pelos dígitos individuais dados pelas <strong><em>variáveis</em></strong> "<strong>SENHA_IN_1</strong>", "<strong>SENHA_IN_2</strong>", e "<strong>SENHA_IN_3</strong>", é preciso "juntar" esses três dígitos em um único valor e então proceder à verificação se a Senha está correta. Como "<strong>SENHA_IN_1</strong>" tem o <strong><em>peso das centenas</em></strong>, este dígito deve ser multiplicado por <strong><em>100</em></strong>. E como "<strong>SENHA_IN_2</strong>" tem o <strong><em>peso das dezenas</em></strong>, este dígito deve ser multiplicado por <strong><em>10</em></strong>. E como "<strong><em>SENHA_IN_3</em></strong>" tem o <strong><em>peso das unidades</em></strong>, já está com o valor adequado para constituir a Senha atualmente inserida (e que está sendo exibida no Display). Isto é feito na <strong><em>linha 957</em></strong> da função, onde as três parcelas são somadas. Então basta comparar o valor resultante com a <strong><em>Senha do Sistema</em></strong>, o que é feito na <strong><em>linha 959</em></strong> da função, sendo o resultado desta comparação ("<strong><em>true</em></strong>" ou "<strong><em>false</em></strong>") informado no retorno da função.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Como dito, uma Máquina de apenas três estados, controla todo o mecanismo de entrada da Senha e verificação da mesma. Pode parecer difícil de visualizar ou acreditar nisso, mas o processo é muito simples conforme veremos a seguir.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Primeiro, vamos ver a definição dos três estados da <strong><em>Máquina de Estados</em></strong>, o que é feito em uma <strong><em>lista enumerada</em></strong> mostrada 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/9253820695?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253820695?profile=RESIZE_710x" class="align-center" width="476" height="178"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Notar que cada estado definido, está marcado com uma cor diferente (<strong><em>verde</em></strong>, <strong><em>azul</em></strong>, e <strong><em>laranja</em></strong>). Isto facilitará visualizar na <strong><em>Máquina de Estados</em></strong>, justamente a execução de cada um destes estados. Notar também que junto às definições, está a descrição do que é feito em cada estado, embora o próprio nome destes já deixe isso praticamente óbvio.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A <strong><em>Máquina de Estados</em></strong> está implementada na <em>função</em> "<strong><em>loop</em></strong>" do <strong><em>Arduino</em></strong>. Vejamos sua estrutura, o que é 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/9253822068?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253822068?profile=RESIZE_710x" class="align-center" width="367" height="682"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Observar as três regiões marcadas com as mesmas três cores correspondentes aos três estados da Máquina (definidos anteriormente na lista enumerada). Cada região corresponde à execução de um único estado. Quando a <em>função</em> "<strong><em>loop</em></strong>" é executada (e sabemos que ela é executada de forma cíclica), <strong><em>somente um dos estados será executado</em></strong>, e quem determina isso é a <strong><em>variável local</em></strong> de nome "<strong>estado_MAQ</strong>" (definida na área marcada na <strong><em>cor amarela</em></strong> na figura anterior), que é do tipo <strong><em>byte</em></strong> e também "<strong><em>static</em></strong>" (indicando que seu valor é mantido mesmo quando a função termina sua execução). Esta variável então <strong><em>assumirá apenas um dos três estados definidos</em></strong>. Mas quando o "<strong><em>loop</em></strong>" é executado pela primeira vez (e somente na primeira vez!!!) essa variável já indica o estado "<strong>SENHA_iniciar</strong>", o que garante que a Máquina tem um estado definido quando o Sistema inicia (ver área marcada em amarelo na figura).</span></p>
<p><span style="font-size: 12pt;"> E o próximo estado da Máquina, dependerá do estado atual em que ela se encontra e do que acontece neste estado. Vejamos então o funcionamento desta Máquina, conforme descrito a partir do seu <strong><em>estado inicial</em></strong>, o que é descrito a seguir.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> No <strong><em>estado</em></strong> "<strong>SENHA_iniciar</strong>", que começa na <strong><em>linha 1021</em></strong>, as três variáveis "<strong>SENHA_IN_1</strong>", "<strong>SENHA_IN_2</strong>", e "<strong>SENHA_IN_3</strong>", que armazenam os valores que são mostrados nos três Displays, são zeradas, o que implica que veremos "<strong>000</strong>" nos Displays. Já a variável "<strong>DISPLAY_SENHA</strong>" é setada com valor "<strong>1</strong>", o que significa que o <strong><em>Display</em></strong> "<strong>1</strong>" está atualmente selecionado para a entrada de dígito da Senha. Ainda neste estado, os dois LEDs, "<strong>OK</strong>" e "<strong>ERRO</strong>" são desligados. Então a variável "<strong>estado_MAQ</strong>" é setada na <strong><em>linha 1032</em></strong>, para que a Máquina siga para o <strong><em>estado</em></strong> "<strong>SENHA_inserir</strong>".</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> No <strong><em>estado</em></strong> "<strong>SENHA_inserir</strong>" (que começa na <strong><em>linha 1038</em></strong>) é onde ocorrem todas as operações relacionadas à <strong><em>entrada de Senha</em></strong>. Na <strong><em>linha 1039</em></strong>, o teste "<strong>if</strong>" verifica através da função "<strong>verifica_BOTAO_trigger_ON</strong>" <em><u>se</u></em> o <strong><em>Botão</em></strong> "<strong>1</strong>" foi acionado, e caso isso tenha ocorrido, o "<strong><em>switch</em></strong>" na <strong><em>linha 1041</em></strong> testa a variável "<strong>DISPLAY_SENHA</strong>" e conforme o valor desta (<strong>1</strong>, <strong>2</strong>, ou <strong>3</strong>) teremos que ou a variável "<strong>SENHA_IN_1</strong>", ou a "<strong>SENHA_IN_2</strong>", ou a "<strong>SENHA_IN_3</strong>", será <strong><em>decrementada</em></strong>, já que o <strong><em>Botão</em></strong> "<strong>1</strong>" tem esta funcionalidade.</span></p>
<p><span style="font-size: 12pt;"> Mas se o <strong><em>Botão</em></strong> "<strong>1</strong>" não foi acionado, então o "<strong>else if</strong>" na <strong><em>linha 1061</em></strong> verifica se o <strong><em>Botão</em></strong> "<strong>2</strong>" foi acionado, e de forma semelhante ao já descrito, uma das variáveis dos Displays será <strong><em>incrementada</em></strong>, já que o <strong><em>Botão</em></strong> "<strong>2</strong>" tem esta funcionalidade.</span></p>
<p><span style="font-size: 12pt;"> Mas se o <strong><em>Botão</em></strong> "<strong>2</strong>" não foi acionado, então o "<strong>else if</strong>" na <strong><em>linha 1083</em></strong> verifica se o <strong><em>Botão</em></strong> "<strong>3</strong>" foi acionado, e caso isto tenha ocorrido, então é selecionado o próximo Display através do incremento da variável "<strong>DISPLAY_SENHA</strong>". Mas aqui há mais coisas pra fazer, pois se "<strong>DISPLAY_SENHA</strong>" foi incrementada para além de "<strong>3</strong>" (ou seja, foi para "4"), significa que foi concluída a inserção dos 3 dígitos da Senha, o que é testado na <strong><em>linha 1087</em></strong>. Neste caso, deve ser verificado se a Senha inserida está correta, o que é testado na <strong><em>linha 1089</em></strong> via função "<strong>verifica_SENHA</strong>" (que já analisamos), e se esta função retorna "<strong><em>true</em></strong>" então significa que a senha está correta, e neste caso o <strong><em>LED</em></strong> "<strong>OK</strong>" é ligado (na <strong><em>linha 1091</em></strong>). Mas se a função retornar "<strong><em>false</em></strong>", então a Senha inserida está incorreta, e o <strong><em>LED</em></strong> "<strong>ERRO</strong>" é ligado (na <strong><em>linha 1095</em></strong>). Independente se a Senha está correta ou não, como a entrada de Senha foi concluída, o Sistema deve aguardar antes de reiniciar todo o processo de entrada de Senha, e para isto na <strong><em>linha 1098</em></strong> a variável "<strong><em>estado_MAQ</em></strong>" é setada para seguir para o <strong><em>estado</em></strong> "<strong>SENHA_aguardar</strong>".</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Uma vez no <strong><em>estado</em></strong> "<strong>SENHA_aguardar</strong>" (que começa na <strong><em>linha 1105</em></strong>), novamente é aguardado que o <strong><em>Botão</em></strong> "<strong>3</strong>" seja acionado. Porém quando isto for detectado, simplesmente a <strong><em>Máquina de Estados</em></strong> é direcionada para o <strong><em>estado</em></strong> "<strong>SENHA_iniciar</strong>", o que reinicia todo o processo de inserção de Senha.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Como se vê, o processo é simples. Uma coisa importante a notar, é que a lógica mais complexa usada no <strong><em>processamento dos estados</em></strong>, é o "<strong>if / else</strong>" (o "<strong><em>switch</em></strong>" também é uma <em>forma</em> "<em>sintética</em>" de "<strong>if /else</strong>"). Isto é uma das coisas que garante a extrema confiabilidade do funcionamento da <strong><em>Máquina de Estados</em></strong>, implicando que a mesma seja praticamente <strong><em>livre de bugs</em></strong> (que são muito fáceis de ocorrer em lógicas malucas ou complexas), e ainda mantendo uma grande simplicidade.</span></p>
<p><span style="font-size: 12pt;"> </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 <strong><em>código</em></strong> e arquivos para <strong><em>Simulação</em></strong> estão neste link: <a href="https://storage.ning.com/topology/rest/1.0/file/get/9253823895?profile=original" target="_blank" rel="noopener">"<span style="text-decoration: underline;"><em>Senha_7_seg_01.zip</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;"> Link para ver ou fazer download do vídeo da Simulação: <a href="https://1drv.ms/v/s!Amu91_NWVNMvhQX8NMeWk1qvzSju?e=0cmWh9" target="_blank" rel="noopener">"<em><span style="text-decoration: underline;">video</span></em>"</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;"> A simulação ajuda a testar mais rapidamente o Sistema, permitindo se ver o funcionamento do Sistema sem precisar montar o circuito. Além disso possibilita que aqueles que não tem o Hardware em mãos, possam testar o Sistema e aprender com isso, fazendo suas experiências.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Em caso de dúvidas, não deixe de perguntar.</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> olá Ester.
Estou publ…tag:labdegaragem.com,2021-07-15:6223006:Comment:8714362021-07-15T15:49:55.664ZElcids Chagashttps://labdegaragem.com/profile/ElcidsChagas
<p><span style="font-size: 12pt;">olá Ester.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Estou publicando uma implementação para este Sistema que vc descreveu e pediu ajuda aqui. Como vc disse que não sabe por onde iniciar, então reuni as informações que vc passou (por exemplo, uso do <strong><em>Decoder 4511</em></strong>), e por este motivo a implementação é bastante completa permitindo que seja desenvolvida na direção que vc ou outros…</span></p>
<p><span style="font-size: 12pt;">olá Ester.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Estou publicando uma implementação para este Sistema que vc descreveu e pediu ajuda aqui. Como vc disse que não sabe por onde iniciar, então reuni as informações que vc passou (por exemplo, uso do <strong><em>Decoder 4511</em></strong>), e por este motivo a implementação é bastante completa permitindo que seja desenvolvida na direção que vc ou outros desejem. Esta também é uma ótima oportunidade para mostrar a implementação de coisas que podem até parecer complexas a princípio, mas que são na realidade bem simples. Para isto, o Hardware é descrito em detalhes, e o código está totalmente organizado (de forma hierárquica) e comentado funcionalmente (o que é indispensável para se entender sem esforço, como ele funciona). Mesmo assim irei descrever aqui, alguns pontos principais para aqueles que não querem se aprofundar e desejam apenas utilizar os recursos. Aconselho a quem for utilizar, ler integralmente o texto aqui publicado.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Implementei também uma <strong><em>Simulação</em></strong> no <strong><em>Proteus</em></strong>, a qual permite testar o funcionamento do Sistema e também medir alguns parâmetros importantes. Sobre a Simulação, alguns aspectos são apresentados mais adiante.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> O código implementado e os arquivos para a Simulação, estão disponíveis para download no final deste post (há também um vídeo mostrando a execução da simulação).</span></p>
<p><span style="font-size: 12pt;"> </span><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <span style="text-decoration: underline; font-size: 14pt;"><strong><em>Sobre o Circuito</em></strong></span></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A implementação do Hardware usa o <strong><em>Arduino UNO</em></strong>, o <strong><em>Decoder CMOS</em></strong> de <strong><em>7 segmentos 4511</em></strong> (mais "corretamente" o <strong>4511B</strong>), e <strong><em>três</em></strong> <strong><em>Displays</em></strong> de <strong><em>7 segmentos</em></strong> de <strong><em>Katodo Comum</em></strong> (já que o <strong><em>4511</em></strong> permite acionar diretamente esse tipo de Display). Há também os <strong><em>três Botões</em></strong> usados para inserção da <strong><em>Senha</em></strong>, e <strong><em>dois LEDs</em></strong> que indicam se a Senha inserida está correta ou não. Os demais componentes são <strong><em>Resistores</em></strong> e <strong><em>Transistores</em></strong>. O circuito implementado pode ser visto 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/9253746699?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253746699?profile=RESIZE_710x" width="408" class="align-center"/></a> </span><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Vamos falar um pouco então sobre os elementos usados neste Hardware:</span></p>
<p><span style="font-size: 12pt;"> </span><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>1)</em></strong> <strong>Arduino</strong>: está sendo usado o <strong><em>UNO</em></strong> (uma vez que foi este o <strong><em>Arduino</em></strong> informado no tópico em questão), e isto facilita muito "traduzir" este Sistema para outros Arduinos. Conforme pode ser visto na figura anterior, são usados <strong><em>4 pinos</em></strong> para especificar um valor de <strong><em>0</em></strong> a <strong><em>9</em></strong> para o <strong><em>Decoder 4511</em></strong>, sendo estes pinos o <strong><em>4</em></strong>, <strong><em>5</em></strong>, <strong><em>6</em></strong>, e <strong><em>7</em></strong>, conectados respectivamente aos <strong><em>bits</em></strong> "<strong>A</strong>" (ou <strong>bit</strong> "<strong>0</strong>"), "<strong>B</strong>" (ou <strong>bit</strong> "<strong>1</strong>"), "<strong>C</strong>" (ou <strong>bit</strong> "<strong>2</strong>"), e "<strong>D</strong>" (ou <strong>bit</strong> "<strong>3</strong>") do <strong><em>4511</em></strong>. Mas poderiam ser usados quaisquer pinos de <strong><em>saída Digital</em></strong> do <strong><em>Arduino</em></strong> e em qualquer ordem desejada, pois o código implementado permite isso.</span></p>
<p><span style="font-size: 12pt;"> Para o <strong><em>controle ON/OFF</em></strong> de cada Display, foram usados os <strong><em>pinos</em></strong> "<strong>A1</strong>", "<strong>A2</strong>", e "<strong>A3</strong>" do <strong><em>UNO</em></strong>. Aqui também, quaisquer pinos podem ser usados e em qualquer ordem.</span></p>
<p><span style="font-size: 12pt;"> Para leitura dos estados dos três <strong><em>Botões</em></strong> e controle dos dois <strong><em>LEDs</em></strong>, outros <strong><em>5 pinos</em></strong> são usados, e novamente podem ser especificados quaisquer outros pinos.</span></p>
<p><span style="font-size: 12pt;"> Assim ainda restam disponíveis <strong><em>8 pinos</em></strong> do <strong><em>Arduino</em></strong> <strong><em>UNO</em></strong>. Observar que os pinos restantes permitem que se use algumas <em>funções especiais</em>, como pelo menos uma entrada do <strong>ADC</strong> (pino A0), <strong><em>Interface I2C</em></strong> (pinos A4 e A5), <strong><em>Interrupções Externas</em></strong> (pinos 2 e 3, mas há também as Interrupções do tipo "<em>pin change</em>" para outros pinos), <strong><em>PWM</em></strong> (pino 3), além da conexão ao <strong><em>Terminal do Arduino</em></strong> via <strong><em>Serial 0</em></strong> (pinos 0 e 1). Claro, todos os 8 pinos também podem ser usados para I/O convencional. Então quando vc escolher qualquer outra combinação de pinos para o Sistema, analise antes qual é a que melhor se encaixa para suas necessidades.</span></p>
<p><span style="font-size: 12pt;"> </span><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>2)</em></strong> <strong>Decoder 7 segmentos e Displays</strong>: está sendo utilizado o <strong>4511</strong>. Este <strong><em>Decoder</em></strong> embora seja <strong><em>CMOS</em></strong>, possui <em>internamente</em> em cada uma de suas <em>7 saídas</em> para os LEDs de segmentos, um <strong><em>Driver</em></strong> com <strong><em>Transistor Bipolar</em></strong> para fornecer a corrente para os respectivos LEDs (claro, via Resistor externo para limitar e determinar a corrente de saída). É um Decoder para Displays de <strong><em>Katodo Comum</em></strong>. As <strong><em>entradas</em></strong> "<strong>LT</strong>" (<em>Light Test</em>), e "<strong>BI</strong>" (<em>Blanking Input</em>), são ativas em "0" e como não estão sendo usadas, são ligadas a "<strong>1</strong>" (os 5V da alimentação). A <strong><em>entrada</em></strong> "<strong>LE</strong>" (<em>Latch Enable</em>) deve ser ligada ao "<strong>0</strong>" (GND do circuito), para que o <strong><em>Latch interno</em></strong> do <strong><em>4511</em></strong> fique "transparente", ou seja desabilitado, para que as saídas de 7 segmentos sempre estejam reproduzindo o valor binário presente nas entradas A, B, C, e D.</span></p>
<p><span style="font-size: 12pt;"> Os <strong><em>Resistores</em></strong> conectados às saídas <strong><em>QA</em></strong> a <strong><em>QG</em></strong> do <strong><em>4511</em></strong>, determinam a corrente para cada segmento. Para os valores no circuito, <strong><em>330 Ω</em></strong>, a corrente será algo próximo a <strong><em>10mA</em></strong>. Para este cálculo, desconte de 5V, a tensão sobre um LED de segmento, e então terá a tensão sobre o Resistor. No caso, vamos considerar que o LED do Display tem uma tensão <strong><em>Anodo/Katodo</em></strong> de <strong><em>1.5V</em></strong> quando ligado. Então sobre o Resistor teremos <strong><em>5V - 1.5V = 3.5V</em></strong> (aqui estamos "desprezando" a queda no <strong><em>Transistor Bipolar interno</em></strong> do <strong><em>4511</em></strong>). Então a <strong><em>corrente</em></strong> será <strong><em>3.5V / 330 Ω ≈ 10.6 mA</em></strong>. Da mesma forma, pode-se também calcular o Resistor, especificando-se a corrente desejada, mas evite passar de 20mA, a fim de limitar o total de corrente fornecido pelo <strong><em>4511</em></strong> (veja o datasheet do mesmo para mais detalhes). Caso correntes bem maiores sejam desejadas, pode-se usar Transistores adicionais (tipo <strong><em>NPN</em></strong>) nos pinos de segmentos.</span></p>
<p><span style="font-size: 12pt;"> Observar que estamos considerando que os <strong><em>Transistores</em></strong> <strong><em>Q1</em></strong> a <strong><em>Q3</em></strong> estão funcionalmente saturados quando acionados pelas <strong><em>saídas</em></strong> do <strong><em>Arduino</em></strong>. Isto é fácil de garantir, supondo-se um <strong><em>HFE</em></strong> <em>médio</em> (por exemplo <em>100</em>) e escolhendo-se uma corrente de base em torno de <em>1 mA</em>. Caso alguém queira saber sobre estes cálculos, pergunte aqui neste mesmo tópico, ou me contate via email do LDG.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em><u>Nota Importante</u></em></strong>: é possível dispensar <strong><em>Q1</em></strong> a <strong><em>Q3</em></strong> e <strong><em>R11</em></strong> a <strong><em>R13</em></strong>. Para isso basta que se ligue as saídas do Arduino (no caso pinos <strong><em>A1</em></strong>, <strong><em>A2</em></strong>, e <strong><em>A3</em></strong>), diretamente aos <strong><em>Katodos</em></strong> dos <strong><em>Displays</em></strong>. Nenhuma alteração no código é necessária, uma vez que os Transistores usados são do tipo <strong><em>PNP</em></strong>, o que significa que o código aciona estes por <strong><em>Lógica</em></strong> "<strong>LOW</strong>" (isto foi feito propositalmente). Notar porém, que o uso dos Transistores traz uma maior flexibilidade na escolha das correntes dos segmentos dos Displays, já que a corrente confiável para uma <strong><em>saída</em></strong> do <strong><em>Arduino</em></strong> é de <strong><em>20mA</em></strong>, e <strong><em><u>NÃO</u></em></strong> <strong><em>40mA</em></strong> como muitos adoram proclamar!!! Vejam: 40mA é para os "<strong><em>limites máximos absolutos</em></strong>" e não preciso dizer mais nada. Mas há um ponto que ajuda muito aqui: os Displays são acionados de forma multiplexada, e sempre há apenas um único Display acionado de cada vez. Isso significa que a corrente média total de um Display será 1/3 (um terço, já que são três Displays) da corrente determinada pelos Resistores dos segmentos. Como temos 7 segmentos, se a corrente individual é de 10 mA, então a corrente total seria 7 x 10mA = 70mA quando todos os segmentos estiverem ligados (reproduzindo o número "8"), mas a corrente efetiva seria <strong><em>1/3</em></strong> disso, ou seja: <strong><em>70mA / 3 = 23mA</em></strong>. Claro, isso é ligeiramente acima da corrente "segura" para um pino do <strong><em>UNO</em></strong>, mas considerando-se que dificilmente todos os segmentos estarão ligados nos três Displays, então esse limite marginal pode ser desconsiderado. Mas de todo caso, o uso dos <strong><em>Transistores</em></strong> <strong>Q1</strong> a <strong>Q3</strong> é mais sensato, garantindo inclusive que não se extrapole a máxima corrente de todos os pinos somados do processador do <strong><em>UNO</em></strong> (o <strong><em>AtMega328</em></strong>).</span></p>
<p><span style="font-size: 12pt;"> </span><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>3)</em></strong> <strong>Botões</strong>: para estes, estão sendo utilizados os <strong><em>Pullups internos</em></strong> do <strong><em>Processador</em></strong> do <strong><em>UNO</em></strong>, o que dispensou o uso de Resistores externos. A Lógica implementada no código faz o "<strong>debouncing</strong>" dos Botões <em><u>automaticamente</u></em> (e sem travar a execução do código). Isso permite dispensar <strong><em>Capacitores</em></strong> externos para o "<strong>debouncing</strong>" (e eventuais <strong><em>Diodos de Proteção</em></strong>, necessários se os Capacitores tivessem valores relativamente altos).</span></p>
<p><span style="font-size: 12pt;"> </span><span style="font-size: 12pt;"> </span></p>
<p></p>
<p><span style="font-size: 12pt;"> <span style="text-decoration: underline; font-size: 14pt;"><strong><em>Sobre a Varredura dos Displays e dos Botões</em></strong></span></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Como pode ser visto na figura inicial que mostra o circuito do Sistema, os Displays são acionados por meio da varredura dos mesmos, ou seja, a exibição dos valores em cada um dos três Displays, é feita de forma <strong><em>multiplexada</em></strong>. Logo, somente um Display está efetivamente "ligado" num determinado momento. A <strong><em>frequência de varredura</em></strong> (ou <strong><em>taxa de</em></strong> "<strong><em>Refresh</em></strong>"), foi escolhida como sendo <strong><em>50 Hz</em></strong>. Vamos entender os motivos disso. Primeiro, deve ser uma frequência que não permita a retina do olho humano acompanhar o <strong><em>liga/desliga</em></strong> dos Displays, dando a impressão que todos os três Displays estão sempre ligados, e portanto quanto maior esta frequência, melhor. E para que as demais funcionalidades do código sejam executadas sem haver preocupação em manter a <strong><em>taxa de varredura do Display</em></strong>, essa varredura é executada em uma <strong><em>rotina de Interrupção</em></strong> (<strong><em>ISR</em></strong>), e para gerar essa Interrupção em uma taxa constante, é utilizado o "<strong>TIMER1</strong>" do <strong>Hardware</strong> do <strong><em>Processador</em></strong> do <strong><em>Arduino</em></strong>. Assim na inicialização do Sistema, o código programa o "<strong>TIMER1</strong>" para gerar a <strong><em>taxa de varredura dos Displays</em></strong>. A cada interrupção, é feita a varredura de um único Display. Logo, para varrer os três Displays a <strong><em>50 Hz</em></strong>, é necessário uma <strong><em>taxa de Interrupção</em></strong> de <strong><em>3 x 50Hz = 150 Hz</em></strong>. Os detalhes do código que fazem essa varredura são mostrados mais adiante. Observar que a <strong><em>ISR</em></strong> (<strong><em>rotina de Interrupção</em></strong>) deve ser eficiente, para garantir que as demais funcionalidades do Sistema sejam executadas de forma "fluida", ou seja, sem parecer que as <strong><em>Interrupções</em></strong> estão ocorrendo <strong><em>150 vezes por segundo</em></strong>.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> No código implementado, a <strong><em>varredura dos Displays</em></strong> de fato é muito eficiente, e consome efetivamente pouco tempo. Por este motivo, para tornar o Sistema também "despreocupado" com a <strong><em>leitura</em></strong> e <strong><em>gerenciamento</em></strong> dos <strong><em>Botões</em></strong>, essa tarefa também é executada na mesma <strong><em>rotina de Interrupção</em></strong> do "<strong>TIMER1</strong>". Essencialmente, ali é feita a leitura dos estados dos Botões e conforme estes estados, é determinado se um Botão foi <strong><em>acionado</em></strong>, <strong><em>desacionado</em></strong>, ou se está pressionado por um determinado tempo. O código implementa isso de forma enxuta, longe de sacrificar tempo de processamento do restante do Sistema.</span></p>
<p><span style="font-size: 12pt;"> Se forem acrescentados ao Sistema dispositivos "<strong>One Wire</strong>" (ex.: <strong><em>Sensor DS18B20</em></strong>) ou semelhante (ex.: <strong><em>DHT11</em></strong> ou <strong><em>DHT22</em></strong>), alguns cuidados devem ser tomados para se garantir os <strong>tempos de</strong> "<strong>slot</strong>" para estes dispositivos. Mas é algo perfeitamente factível, e posteriormente posso mostrar como fazer isso (há pelo menos três formas de implementação).</span></p>
<p><span style="font-size: 12pt;"> Para <strong>dispositivos I2C</strong>, nenhum cuidado especial é necessário, uma vez que estes também são cadenciados por <strong><em>IRQ</em></strong> (<strong><em>Interrupt Request</em></strong>) e não há um momento específico para que estas IRQs sejam atendidas.</span></p>
<p><span style="font-size: 12pt;"> Quaisquer dúvidas relacionadas, posso responder aqui mesmo neste tópico.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <span style="text-decoration: underline; font-size: 14pt;"><strong><em>Sobre o Código e Funcionamento do Sistema</em></strong></span></span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A <strong><em>Senha do Sistema</em></strong> é definida no início do código, 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></p>
<p><span style="font-size: 12pt;"><a href="https://storage.ning.com/topology/rest/1.0/file/get/9253749853?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253749853?profile=RESIZE_710x" width="468" height="112" class="align-center"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Há no Sistema dois <strong><em>LEDs</em></strong>, um <strong><em>Verde</em></strong> (ou <strong><em>LED</em></strong> "<strong>OK</strong>") e um <strong><em>Amarelo</em></strong> (ou <strong><em>LED</em></strong> "<strong>ERRO</strong>"). O LED Verde é utilizado para sinalizar quando a Senha correta é inserida, e o Amarelo indica quando a Senha inserida está incorreta. A definição no código para a configuração de Hardware dos LEDs, pode ser vista 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/9253749900?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253749900?profile=RESIZE_710x" class="align-center" width="423" height="167"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em>Três Botões</em></strong> controlam a operação do Sistema. O <strong><em>Botão</em></strong> "<strong>1</strong>" decrementa o valor exibido no Display atualmente selecionado. O <strong><em>Botão</em></strong> "<strong>2</strong>" incrementa o valor exibido. Já o <strong><em>Botão</em></strong> "<strong>3</strong>" tem várias funções, sendo a mais comum, selecionar o próximo Display para entrada da Senha.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> O funcionamento do código é bastante simples: enquanto no "<strong>background</strong>" a <strong><em>varredura dos Displays</em></strong> e dos <strong><em>Botões</em></strong> é executada quando as <strong><em>Interrupções</em></strong> do <strong><em>TIMER1</em></strong> ocorrem (na taxa de <strong><em>150 Hz</em></strong>), temos que no "<strong>foreground</strong>" (ou execução "normal") o código decrementa ou incrementa o valor exibido no Display atualmente selecionado conforme acionamento dos <strong><em>Botões</em></strong> "<strong>1</strong>" ou "<strong>2</strong>". E quando o <strong><em>Botão</em></strong> "<strong>3</strong>" é acionado, então o código simplesmente seleciona o próximo Display.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Para cada um dos três Displays há uma variável do tipo "byte", que pode assumir valores de <strong>0</strong> a <strong>9</strong>. São exatamente o valor dessas três variáveis que são exibidas pelo <strong><em>mecanismo de varredura do Display</em></strong> (no "<strong>background</strong>", ou seja, na <strong><em>rotina de Interrupção</em></strong>). E no início de tudo, as três variáveis estão zeradas, o que resulta em exibir "<strong>000</strong>" nos Displays. Há também um variável do tipo byte que indica qual Display está atualmente selecionado, e a mesma assume valores de <strong>1</strong> a <strong>3</strong>. E no início, esta variável assume o valor "<strong>1</strong>", selecionando assim o <strong><em>Display</em></strong> "<strong>1</strong>" para a entrada de um Dígito da Senha (neste caso o Dígito das centenas). A figura a seguir mostra as três variáveis para os valores exibidos em cada Display, além da variável que indica qual Display está atualmente selecionado:</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/9253750491?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253750491?profile=RESIZE_710x" class="align-center" width="357" height="246"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Se um Display está no <strong><em>valor</em></strong> "<strong>0</strong>" e é <strong><em>decrementado</em></strong>, ele "recicla" para "<strong>9</strong>". E se um Display está no valor "<strong>9</strong>" e é <strong><em>incrementado</em></strong>, ele recicla para "<strong>0</strong>". Então o que o código tem que fazer é verificar quando cada Botão é acionado e aplicar as ações descritas.</span></p>
<p><span style="font-size: 12pt;"> Mas quando o <strong><em>Display</em></strong> "<strong>3</strong>" está selecionado e o <strong><em>Botão</em></strong> "<strong>3</strong>" é acionado, isso deve ser interpretado como "<strong><em>fim da entrada de Senha</em></strong>", e o Sistema então deve verificar se a Senha mostrada nos Displays, corresponde à <strong><em>Senha do Sistema</em></strong>.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Se a Senha que foi "inserida" via Displays estiver correta, então o <strong><em>LED Verde</em></strong> (<strong><em>LD1</em></strong> no circuito) acende. Mas se a Senha estiver incorreta, então o <strong><em>LED Amarelo</em></strong> (<strong><em>LD2</em></strong>) acende.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Após a verificação da Senha, o Sistema fica aguardando que o <strong><em>Botão</em></strong> "<strong>3</strong>" seja novamente acionado, para reiniciar uma nova entrada de Senha. Neste ponto, os dois LEDs apagam, sendo selecionado o <strong><em>Display</em></strong> "<strong>1</strong>" para entrada de um Dígito da Senha, e os Displays exibem "<strong>000</strong>", e portanto o Sistema volta ao "início".</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A forma mais simples e confiável de implementar esse sequenciamento do código, é através de uma <strong><em>Máquina de Estados</em></strong>, que é mostrada mais a frente neste post. Apenas <strong><em>3 estados</em></strong> foram necessários para implementar todo o processamento.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Há no código um bloco que trata de todo o <strong><em>gerenciamento de leitura dos Botões</em></strong>, e que é executado no "<strong>background</strong>", ou seja, na <strong><em>rotina de Interrupção</em></strong> do <strong><em>TIMER1</em></strong> (onde também é feita a varredura dos Displays). Como dito anteriormente, este bloco de código verifica se um Botão foi acionado ou desacionado, e também "mede" o tempo que um Botão está acionado. Estas informações estão disponíveis para serem usadas no "<strong>foreground</strong>" do código permitindo assim que este tome as ações conforme os estados dos Botões. Mas para que isto seja possível, é necessário que os Botões sejam definidos no Sistema. Esta definição é simples e consiste de duas etapas. A primeira é a definição dos <strong><em>pinos</em></strong> de Hardware onde os Botões estão conectados, 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></p>
<p><span style="font-size: 12pt;"><a href="https://storage.ning.com/topology/rest/1.0/file/get/9253752266?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253752266?profile=RESIZE_710x" class="align-center" width="417" height="178"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A segunda etapa é a criação de <strong><em>estruturas de dados</em></strong> para armazenar os <strong><em>status dos Botões</em></strong>, e de funções que configuram estes Botões e atualizam os status dos mesmos. Isto pode ser visto 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/9253752293?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253752293?profile=RESIZE_710x" class="align-center" width="385" height="380"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Caso fossem incluídos mais Botões no Sistema, bastaria se estender a mesma ideia mostrada na figura, acrescentando as definições para estes Botões juntamente aos já existentes.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Notar que a função "<strong>atualiza_Status_Botoes</strong>" será executada no "<strong>background</strong>", ou seja, na <strong><em>rotina de Interrupção</em></strong> do <strong><em>TIMER1</em></strong>. Ela está incluída na figura anterior para se mostrar como é simples a definição completa para uso de um Botão no Sistema. Esta função será especificada como a que justamente atualiza os status dos Botões, através de um "<strong>HOOK</strong>" na <strong><em>rotina de Interrupção</em></strong> (mostrado mais adiante quando a <strong><em>ISR</em></strong> for apresentada).</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Em relação ao <strong><em>Decoder 4511</em></strong>, são necessários <strong><em>4 pinos</em></strong> do <strong><em>Arduino</em></strong> para se especificar qual valor será exibido em um determinado momento. A definição destes pinos é mostrada 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/9253753853?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253753853?profile=RESIZE_710x" class="align-center" width="422" height="156"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Como já dito, quaisquer pinos podem ser especificados, e em qualquer ordem, pois o código se encarrega de setar cada um deles para reproduzir o valor binário para o <strong><em>Decoder 4511</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;"> Para o <strong><em>controle ON/OFF</em></strong> dos três Displays, <strong><em>3 pinos</em></strong> devem ser especificados para este controle. Novamente, quaisquer pinos podem ser especificados, e em qualquer ordem. No código, esta definição pode ser visto 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/9253754077?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253754077?profile=RESIZE_710x" class="align-center" width="403" height="190"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> A figura a seguir, mostra a captura da tela da Simulação do Sistema no Proteus, em um momento que o <strong><em>Display</em></strong> "<strong>1</strong>" está sendo varrido, e por isso apenas o mesmo aparece "ligado" na figura exibindo o valor "3":</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/9253755483?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253755483?profile=RESIZE_710x" class="align-center" width="386" height="244"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Como a <strong><em>taxa de varredura</em></strong> total é de <strong><em>150Hz</em></strong> (ou seja, <strong><em>3x 50Hz</em></strong>), então o período de varredura é de <strong><em>6.67ms</em></strong> (ou seja, <strong><em>1 / 150Hz</em></strong>). Logo a cada <strong><em>6.67ms</em></strong> o próximo Display é ligado, sendo setado em <em>binário</em> nos pinos <strong><em>A..D</em></strong> do <strong><em>4511</em></strong>, o valor a ser exibido naquele Display. Ou seja, cada Display fica "ligado" justamente por <strong><em>6.67ms</em></strong>, e fica desligado por <strong><em>13.33ms</em></strong>, o que resulta em um ciclo de <strong><em>20ms</em></strong>, implicando na Frequência individual de <strong><em>50Hz</em></strong> para cada Display.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> <strong><em><u>Obs</u></em></strong>.: a captura da figura anterior foi facilitada pelo fato de que a Simulação executa em um <em>tempo "virtual</em>", completamente independente do tempo real, e o Simulador aumenta ou diminui o step de tempo conforme detalhes da Simulação são executados. Por isso mesmo, quando se executa a simulação, é possível acompanhar partes do processo de varredura, o que causa um efeito que pode parecer "estranho", já que nunca vemos todos os três Displays ligados ao mesmo tempo. Eu disse "partes do processo de varredura", porque enquanto a simulação evolui, o próprio Simulador faz capturas do status desta simulação, para então "printar" estes status na tela do Simulador (aqueles pontinhos vermelhos e azuis que vemos nos prints), e essa taxa de captura não tem nenhuma relação com o conteúdo da simulação, o que resulta em um efeito <strong><em>sub-amostrado</em></strong> (é o mesmo efeito que uma luz stroboscópica existente em pistas de dança das danceterias provoca em nossa retina, resultando em algo semelhante a um vídeo onde faltam cenas). Isto pode ser melhor visto no vídeo da simulação mostrado no final deste post (resulta em um "pisca/pisca" dos valores exibidos no Display, e claro isso é <span style="text-decoration: underline;"><em>apenas</em></span> <em>na Simulação</em>).</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Como já dito, a <strong><em>taxa de varredura</em></strong> total deve ser <strong><em>3 vezes</em></strong> a taxa desejada para um único Display. Assim como desejamos <strong><em>50Hz</em></strong> para cada Display, a taxa total de varredura deve ser <strong><em>150Hz</em></strong>, e isso é definido no código 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></p>
<p><span style="font-size: 12pt;"><a href="https://storage.ning.com/topology/rest/1.0/file/get/9253756663?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253756663?profile=RESIZE_710x" class="align-center" width="431" height="129"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Em uma das simulações, acrescentei um <strong><em>Frequencímetro</em></strong> para medir a <strong><em>frequência de varredura</em></strong> para cada um dos Displays, e o resultado pode ser visto 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/9253758078?profile=original" target="_blank" rel="noopener"><img src="https://storage.ning.com/topology/rest/1.0/file/get/9253758078?profile=RESIZE_710x" class="align-center" width="450" height="267"/></a> </span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p><span style="font-size: 12pt;"> Como pode ser visto na figura anterior, acrescentei também uma <strong><em>chave rotativa</em></strong> (no circuito é a <strong><em>SW1</em></strong>), que permite selecionar em qual dos Displays estaremos medindo a taxa de varredura. Para todos foi medido <strong><em>50Hz</em></strong>, como seria de se esperar.</span></p>
<p><span style="font-size: 12pt;"> </span></p>
<p></p>
<p style="text-align: center;"><span style="font-size: 12pt;"><em>(devido à limitação de espaço este post continua logo a seguir: </em> <span style="text-decoration: underline;"><strong><a href="https://labdegaragem.com/forum/topics/controle-de-display-de-7-segmentos-arduino?commentId=6223006%3AComment%3A871357" target="_blank" rel="noopener">Link</a></strong></span><em>)</em></span></p>
<p></p>
<p></p>
<p></p> Boa noite,
Segue um circuito…tag:labdegaragem.com,2021-07-13:6223006:Comment:8710982021-07-13T01:11:10.924ZCurti Esse Lado Seu Otimistahttps://labdegaragem.com/profile/eijuito
<p>Boa noite,</p>
<p></p>
<p>Segue um circuito para complementar o seu.</p>
<p><a href="https://forum.arduino.cc/t/multiplexing-7-segment-displays-with-a-4511-chip/168138" target="_blank">https://forum.arduino.cc/t/multiplexing-7-segment-displays-with-a-4511-chip/168138</a></p>
<p></p>
<p>Se precisar de algo, é só ver o artigo.</p>
<p></p>
<p>Boa sorte e saúde,</p>
<p> 'Eiju</p>
<p>Boa noite,</p>
<p></p>
<p>Segue um circuito para complementar o seu.</p>
<p><a href="https://forum.arduino.cc/t/multiplexing-7-segment-displays-with-a-4511-chip/168138" target="_blank">https://forum.arduino.cc/t/multiplexing-7-segment-displays-with-a-4511-chip/168138</a></p>
<p></p>
<p>Se precisar de algo, é só ver o artigo.</p>
<p></p>
<p>Boa sorte e saúde,</p>
<p> 'Eiju</p> Boa noite,
Referências para…tag:labdegaragem.com,2021-07-02:6223006:Comment:8709412021-07-02T21:53:37.042ZJosé Gustavo Abreu Murtahttps://labdegaragem.com/profile/GustavoMurta
<p>Boa noite,</p>
<p></p>
<p>Referências para estudos:</p>
<p></p>
<p><strong>Guia completo dos Displays de 7 segmentos – Arduino</strong></p>
<p><a href="https://blog.eletrogate.com/guia-completo-dos-displays-de-7-segmentos-arduino/" target="_blank">https://blog.eletrogate.com/guia-completo-dos-displays-de-7-segmentos-arduino/</a></p>
<p></p>
<p><strong>Arduino – Keypad 4×4 e display digital…</strong></p>
<p></p>
<p>Boa noite,</p>
<p></p>
<p>Referências para estudos:</p>
<p></p>
<p><strong>Guia completo dos Displays de 7 segmentos – Arduino</strong></p>
<p><a href="https://blog.eletrogate.com/guia-completo-dos-displays-de-7-segmentos-arduino/" target="_blank">https://blog.eletrogate.com/guia-completo-dos-displays-de-7-segmentos-arduino/</a></p>
<p></p>
<p><strong>Arduino – Keypad 4×4 e display digital</strong></p>
<p><a href="https://blog.eletrogate.com/arduino-keypad-4x4-e-display-digital/" target="_blank">https://blog.eletrogate.com/arduino-keypad-4x4-e-display-digital/</a></p>
<p></p>
<p><strong>Guia completo do Shield Multi-funções para Arduino</strong></p>
<p><a href="https://blog.eletrogate.com/guia-completo-do-shield-multi-funcoes-para-arduino/" target="_blank">https://blog.eletrogate.com/guia-completo-do-shield-multi-funcoes-para-arduino/</a></p>
<p></p>
<p></p> Bom dia EV,
Este projeto é…tag:labdegaragem.com,2021-07-02:6223006:Comment:8711062021-07-02T13:05:02.102Zmineirin RVhttps://labdegaragem.com/profile/RuiViana
<p>Bom dia EV,</p>
<p></p>
<p>Este projeto é um TCC?</p>
<p></p>
<p> Você já tem um código, (mesmo que não funcione ainda)?</p>
<p> Se tiver um sketch, anexe aqui como um arquivo. Não cole sketch na área de texto do tópico.</p>
<p></p>
<p>O 7 segmento é CC ou AC?</p>
<p></p>
<p>RV mineirin</p>
<p></p>
<p>Bom dia EV,</p>
<p></p>
<p>Este projeto é um TCC?</p>
<p></p>
<p> Você já tem um código, (mesmo que não funcione ainda)?</p>
<p> Se tiver um sketch, anexe aqui como um arquivo. Não cole sketch na área de texto do tópico.</p>
<p></p>
<p>O 7 segmento é CC ou AC?</p>
<p></p>
<p>RV mineirin</p>
<p></p> Boa noite RV
Editei o tópico…tag:labdegaragem.com,2021-07-02:6223006:Comment:8712092021-07-02T01:44:06.104ZE.V.https://labdegaragem.com/profile/EsterVelasquez
<p>Boa noite RV</p>
<p>Editei o tópico e acrescentei um anexo com um print do circuito</p>
<p>Boa noite RV</p>
<p>Editei o tópico e acrescentei um anexo com um print do circuito</p> Boa noite EV
dê mais detalhe…tag:labdegaragem.com,2021-07-02:6223006:Comment:8709342021-07-02T01:37:26.015Zmineirin RVhttps://labdegaragem.com/profile/RuiViana
<p>Boa noite EV</p>
<p></p>
<p>dê mais detalhe sobre o seu projeto para que possamos ajudar melhor.</p>
<p></p>
<p>1. Qual arduino você está usando?</p>
<p>2. Qual modelo do seu display de 7 segmento?</p>
<p>3. Qual decodificador você tem para usar no projeto?</p>
<p>4. Você já tem um sketch, (mesmo que não funcione ainda)?</p>
<p> Se tiver um sketch, anexe aqui como um arquivo. Não cole sketch na área de texto do tópico.</p>
<p></p>
<p>RV mineirin</p>
<p></p>
<p></p>
<p></p>
<p>Boa noite EV</p>
<p></p>
<p>dê mais detalhe sobre o seu projeto para que possamos ajudar melhor.</p>
<p></p>
<p>1. Qual arduino você está usando?</p>
<p>2. Qual modelo do seu display de 7 segmento?</p>
<p>3. Qual decodificador você tem para usar no projeto?</p>
<p>4. Você já tem um sketch, (mesmo que não funcione ainda)?</p>
<p> Se tiver um sketch, anexe aqui como um arquivo. Não cole sketch na área de texto do tópico.</p>
<p></p>
<p>RV mineirin</p>
<p></p>
<p></p>
<p></p>