sexta-feira, 2 de junho de 2017

ESP8266 - Microcontrolador com Wifi e memória Flash

Detalhes sobre o Hardware
O circuito integrado ESP8266 da empresa Expressif é um SoC (System on Chip) bem completo, ele possui portas GPIO, conversor Analígico/Digital de 10 bits, portas PWM, comunicação I²C e SPI, além de uma interface Wifi que implementa o protocolo 802.11 b/g/n com suporte para WPA/WPA2.
O tamanho desse microcontrolador impressiona muito, tem apenas 11,5mm x 11,5mm e depende de poucos recursos externos. Em algumas implementações a antena Wifi é construída como uma trilha na própria placa mas para quem precisa de um alcance maior existe também a opção de uma antena externa.
Sua CPU RISC de 32bits funciona a 80Mhz, bem acima dos microcontroladores existentes nas placas Arduino. O modelo de memória parece um pouco confuso se você não conhece o funcionamento da atualização do firmware. Dentro do microcontrolador existem 3 tipos de memória, 64K de ROM, 96K de RAM e 64K de IRAM (RAM para instruções), essa última memória parece não fazer muito sentido, mas como a CPU foi construída com a arquitetura de Harward sua memória que armazena os programas é diferente da memória que armazena os dados, então essa IRAM possui programas que serão executados e a memória RAM vai ser usada para outras coisas como a pilha e as variáveis dos programas.
Durante o boot o código na memória ROM é executado, ele verifica se o pino GPIO0 está em nível baixo, se estiver então entra em modo de reprogramação e passa a tentar se comunicar via serial com o software de reprogramação, se ele encontrar então vai transferir o novo código para a memória flash. Opa... que memória é essa que eu ainda não havia comentado? Bem, nas placas com o ESP8266 os fabricantes colocam uma memória Flash SPI externa de 512Kb a 4Mb que servirá para armazenar o programa e também dados, quase como se fosse um pequeno cartão SD.
Até aqui tudo bem, entendemos como ele recebe a atualização, mas como o circuito funciona depois do programa ser baixado na memória flash? Basta resetar a placa mantendo o pino GPIO0 em nível alto, em outras palavras, conectando ele ao VCC, dessa forma a rotina na ROM vai entender que é um boot normal, vai copiar o novo programa da memória flash para a memória IRAM e colocar ele para funcionar. Com isso notamos que apesar de existir placas com até 4Mb de flash o limite de IRAM é de 64K.

Detalhes sobre o Software
A Expressif e outras empresas comercializam as placas pelos nomes de suas especificações que vão de ESP-01 até o ESP-14, cada placa com suas particularidades, vamos mostrar apenas algumas, para mais detalhes visite o link do fabricante aqui.
O modelo ESP-01 possui poucos pinos e deixa acesso para o usuário apenas 4 portas, sendo que duas delas são usadas para TX e RX na comunicação serial e as outras duas podem ser usadas normalmente, observando que uma delas é a porta GPIO0 que também é usada para reprogramação durante o boot. O modelo ESP-12 já deixa acesso a todas as portas do microcontrolador, dessa forma ele é bem mais versátil que seu antecessor. Todos os dois utilizam antenas internas, outros modelos possuem recursos diferentes.
O software original disponibiliza uma interface que chamam de interface AT pois utiliza comandos que iniciam pelas letras "AT" da mesma forma que os modens conectados às portas serias dos microcomputadores. Apesar da interface não ser nada amigável, entendemos que ela foi criada dessa forma para atender ao propósito inicial da placa que era servir apenas como uma espécie de placa de rede Wifi para outras placas, como o Arduino. A coisa mudou quando a Expressif disponibilizou o SDK do seu produto na internet e muita gente começou a ver o que era possível fazer com aquele pequeno dispositivo, logo surgiram outras versões de firmwares com interpretadores Lua, Basic e Python além de uma interface com a IDE do Arduino que permite ao usuário programar a sua placa ESP usando a mesma linguagem e ambiente de programação do Arduino com um hardware de melhor performance, menor em tamanho e mais barato (existem sites que vendem a placa por menos de US$ 2,00... isso mesmo menos de dois dólares, eu não escrevi errado).
Apesar do bom trabalho das equipes dos novos firmwares, eles ainda estão em estágio inicial além de que alguns não são compiladores, como o NodeMCU que implementa a linguagem Lua. Nessa arquitetura o seu programa é armazenado na forma de texto em um pseudo filesystem e depois o software interpreta o seu script.
Os recursos desse filesystem e o acesso aos recursos de Wifi que contam com o funcionamento em modo Cliente e modo AP podem ser feitos por meio das bibliotecas fornecidos pelo fabricante, assim como um mini sistema operacional de tempo real chamado RTOS.

Aqui estão as fotos dos modelos ESP-01 e ESP-12 citados no artigo:

ESP-01

ESP-12

Protocolos de Comunicação Serial dos Microcontroladores - SPI, I2C, 1Wire e RS-232

Para que os microcontroladores se comuniquem com outros dispositivos (sejam eles computadores ou outros microcontroladores) podemos usar diversas técnicas, uma das mais simples é usar algum tipo de comunicação serial. Esse nome vem do fato de que os dados são transmitidos bit a bit, por exemplo, se precisamos enviar um byte para outro dispositivo esse byte será enviado um bit por vez e do outro lado os bits recebidos vão recompor o byte transmitido. Parece simples, não é mesmo? Infelizmente o mundo real não é tão bonito assim... para que isso funcione precisamos considerar um monte de outras coisas como ruídos na transmissão, a frequência com que os dados serão enviados, o sincronismo dessa frequência dos dois lados, os limites de inicio e fim de transmissão/recepção e muitos outros.
É possível implementar tudo isso por software? Claro que sim. Mas além de dar um bocado de trabalho teríamos que implementar nossa solução nos vários tipos de hardware que vão usar. Para nossa sorte os microcontroladores mais comuns do mercado já possuem recursos implementados em hardware ou na forma de bibliotecas e a maior vantagem é que eles seguem certos padrões chamados protocolos de comunicação que permitem a comunicação com dispositivos que implementem o mesmo protocolo.
Vamos mostrar a partir daqui quais são os mais comuns no ambiente dos microcontroladores. Neste artigo eu não vou comentar sobre comunicação de rede, mesmo que existam algumas implementações de rede ethernet que, no fim das contas, é um barramento serial, mas foge completamente da simplicidade que quero demonstrar.

Protocolo 1-Wire
Como o nome sugere, esse protocolo usa apenas um fio. Mas isso não é BEM a verdade, ele usa um fio para dados, mas usa também o aterramento ou GND, ou seja, já são dois fios. Em algumas implementações vocês verão o dispositivo usando um terceiro fio para a alimentação, geralmente de 5v, apesar de ser possível utilizar com apenas dois no modo "vampiro". Nesse modo o dispositivo usa a energia que vem na linha de dados e faz uso de um capacitor para continuar alimentado nos períodos em que o sinal de dados fica baixo. O protocolo prevê a existência de um dispositivo Mestre na rede que é chamada de Microlan, os outros dispositivos funcionam no modo Escravo. O dispositivo Mestre envia um comando para que os escravos se identifiquem e inicia a comunicação com cada um deles. Cada dispositivo 1-Wire possui um número único que o identifica.
Exemplo: Termômetro DS18B20 da Dallas Semiconductor.

Protocolo I²C
O nome do protocolo vem de Inter-Integrated Circuit, é permitido o uso de vários Mestres no mesmo barramento e um limite teórico de 127 Escravos. O protocolo usa 2 sinais só para controle, além da alimentação dos circuitos, esses sinais são identificados como SDA (Serial DAta) e SCL (Serial CLock), as duas linhas devem ser ligadas ao VCC por meio de resistores pullup de 1,5KOhms.
O SCL é usado para dar o ritmo da comunicação, isso garante o sincronismo e a exatidão dos pulsos já que transmissor e receptor usam o mesmo sinal de controle. A linha SDA vai portar o dado transmitido/recebido, essa é uma linha bidirecional, ou seja, em certos momentos ela envia e em outros ela recebe dados.
Exemplo: Serial EEPROM 24LC01 e Serial EEPROM AT24C256

Protocolo SPI
O Serial Peripheral Interface ou SPI é outro protocolo serial síncrono assim como o I²C, uma grande diferença é que ele utiliza linhas específicas para transmissão e recepção de dados.
O SPI precisa de 4 sinais de controle nos dispositivos Escravos, no dispositivo Mestre será necessário 3 sinais de controle mais um para cada Escravo que ele vai controlar. Os sinais do protocolo são MISO (Master Input Slave Output) que recebe no Mestre os dados vindo de um Escravo, MOSI (Master Output Slave Input) que o Mestre usa para enviar dados a um Escravo, SCLK (Serial CLocK) que gera o sincronismo para a rede, assim como faz o SCL no I²C e por último o sinal SS (Slave Select) que nos Escravos é uma porta de entrada onde ele recebe um sinal do Mestre indicando que ele está habilitado, caso esteja desabilitado o Escravo deve ignorar o tráfego no barramento. No mestre existem tantos sinais SS quantos forem os escravos, cada um estará ligado a um Escravo e será usado para habilitar esse escravo para uso do Barramento.
Exemplo: Cartões SD

Protocolo RS-232
Esse protocolo foi padronizado em 1969 e ainda está em uso, foi muito utilizado nos ambientes dos antigos mainframes e para comunicação com dispositivos periféricos como modens e impressoras.
O problema de usar esse tipo de protocolo é que os sinais variam entre 3v a 15v positivos ou negativos de acordo com a situação e essa tensão está muito longe do que suportam os microcontroladores que, na maioria, trabalham com 5v ou até mesmo 3,3v. Para permitir que seja utilizado foi feita uma modificação nos sinais criando o que chamam de RS-232 TTL, que é o mesmo protocolo mas com tensões no mesmo nível dos circuitos TTL, ou seja, de 0v até 5v.
Para se comunicar com dispositivos RS-232 nativos os microcontroladores precisam usar um circuito integrado que faça a conversão dos sinais, este circuito se chama MAX232, ele consegue realizar a conversão dos sinais de um padrão para o outro.
Caso os dois dispositivos trabalhem em nível TTL eles podem ser ligados diretamente um ao outro. Este protocolo trabalha ponto a ponto, em outras palavras, só existem dois dispositivos envolvidos e o modo mais simplificado de uso, que é aquele usado nos microcontroladores, prevê a utilização de apenas dois sinais, TX (Transmissão) e RX (Recepção). O TX de um dispositivo é conectado ao RX do outro e vice versa, e eles se comunicam por meio desse protocolo assíncrono.
Exemplo: Modem

Portas Analógicas nos Microcontroladores - ADC e PWM

Vamos falar um pouco sobre portas analógicas tanto de entrada como de saída, para isso temos que entender o que é um sinal analógico e como podemos ler esse sinal.
Um valor digital (ou binário) só possui dois estados que podem ser considerados como 0 e 1 ou ligado e desligado ou alto e baixo, etc. Esse valor quando é lido de uma porta digital só consegue nos retornar uma dessas duas informações discretas. No artigo sobre GPIO eu comentei que várias portas digitais podem ser combinadas para que em uma única operação sejam lidos vários bits simultaneamente, essa afirmação é verdadeira mas temos que perceber que cada bit é um sinal independente, mesmo que no final faça parte de um mesmo dado, por exemplo, quando 8 entradas digitais são lidas por uma porta como um conjunto de 8 bits, ou seja, um byte.

Portas analógicas de entrada
Nos sinais analógicos de entrada os valores podem oscilar entre os limites mínimo e máximo que a porta consegue captar, se ela consegue ler tensões entre 0v e 5v então a tensão aplicada no pino da porta será convertida para um valor digital que poderá ser tratado pelo software. Para fazer isso o microcontrolador se utiliza de um circuito chamado de Conversor Analógico/Digital (ou ADC que significa Analog/Digital Converter), existem diversas formas de funcionamento desses conversores, não entraremos em detalhes por enquanto mas no momento só precisamos saber qual é a sua "resolução" ou qual o número de bits que esse conversor possui. Um conversor de 8 bits consegue ler valores entre 0 e 255 (o máximo de valores é calculado pela fórmula 2 elevado ao numero de bits, como são 256 valores, temos de 0 a 255), então uma tensão 0v na entrada apresenta um valor 0 na porta e uma tensão de 5v apresenta 255 quando é feita a leitura. No Arduino o ADC possui 10 bits retornando assim valores entre 0 e 1023. É possível usar um ADC externo com resoluções maiores.

Portas analógicas de saída
Não é comum que os microcontroladores possuam Conversores Digital/Analógico (DAC), um circuito desse tipo é muito específico e poderia ser usado, por exemplo, para reproduzir músicas pois essa é a base para geração de sons analógicos a partir do armazenamento digital. Mas existe um outro tipo de saída que não é analógica mas que pode, com certas restrições, ser usada com esse propósito. Esse tipo de saída se chama PWM (Pulse With Modulation), esse é um padrão usado por diversos dispositivos como, por exemplo, os servo-motores que se valem desse padrão para que o circuito possa controlar o ângulo em que o servo deve se posicionar.
O PWM gera uma saída com uma frequência fixa onde cada ciclo ocorre em 2 milissegundos, durante esse período o sinal fica parte do tempo em nível alto e parte em nível baixo, ele é um sinal de onda quadrada, não é uma onda senoidal. A frequência é fixa mas podemos controlar por quanto tempo a onda ficará em nível alto e isso é proporcional ao valor que gravamos na porta de saída. No Arduino os pulsos PWM são controlador por meio de um valor de 8 bits, então se usamos o valor 127 a onda vai ficar 50% do tempo alta e 50% do tempo baixa, se diminuímos o valor o tempo de onda alta também diminui e isso pode ser usado, por exemplo, para controlar o brilho de um LED pois quanto mais tempo em nível alto, mais claro o LED vai ficar.
Tudo bem, já percebemos que isso não é nem de longe uma saída analógica, mas como no caso do exemplo com o LED, ele pode funcionar de forma parecida.
Abaixo está a imagem do funcionamento dos pulsos PWM obtida do site do Arduino.



GPIO nos microcontroladores: Uma porta para o mundo externo

GPIO - General Purpose Input/Output

As "Portas" em um microcontrolador e até mesmo em um microprocessador funcionam como uma passagem de informação entre o mundo interno desses dispositivos e o meio externo, são mapeadas por meio de endereços como as memórias e, de fato, em algumas arquiteturas as portas são acessadas como se fossem posições de memória mesmo, mas em outras elas são acessadas por meio de instruções específicas.

Nesse artigo vamos explorar as portas digitais, mas falarei sobre as portas analógicas em outro artigo, vamos começar pelas portas digitais de 1 bit que podem conter apenas uma informação lógica verdadeiro/falso, sim/não, 0/1, ligado/desligado ou qualquer abstração que você possa imaginar.

Portas de Saída
Quando o dispositivo precisa acessar enviar sinais para fora ele utiliza uma porta de saída, dessa forma a informação armazenada na porta se materializa na forma de um sinal digital em um determinado pino do circuito integrado. Para exemplificar, imagine que estamos trabalhando com um circuito que utiliza a tensão de 5v, quando gravamos o valor 0 (zero) na porta de saída teremos no pino do chip relativo à essa porta a tensão 0v, quando gravamos o valor 1 (um) a saída passa para 5v. Essa tensão pode variar um pouco de acordo com o chip mas essa variação não deve ser significativa, na descrição da porta de saída vamos falar sobre os limites aceitáveis.

Portas de Entrada
Para obter um dado do meio externo fazemos o processo inverso, lemos o valor de uma porta de entrada e teremos um bit 0 ou 1 de acordo com a tensão aplicada no seu respectivo pino do circuito integrado, no caso das entradas a tensão deveria ser 0v ou 5v, certo? sim, deveria, mas na prática não é exatamente assim pois como poderíamos tratar um valor de 2,5v? ele está no meio do caminho.
Para solucionar o problema as portas possuem limites para identificar essas tensões de entrada, esses valores variam um pouco de acordo com a tecnologia usada, você consegue essas informações no datasheet do circuito, só para se ter uma ideia os circuitos TTL identificam como 0 as tensões entre 0.0v e 0,8v e identificam como 1 as tensões entre 2.0v e 5.0v, já na tecnologia CMOS essas faixas ficam respectivamente entre 0.0v e 1.5v para o valor 0 e 3.5v a 5.0v para o valor 1.
Então pensamos, existe um buraco nessa faixa de valores possíveis entre 0v e 5v, não é mesmo? O que acontece quando uma tensão está dentro dessa faixa indeterminada? Exatamente isso, o valor a ser considerado será também indeterminado, ou seja, pode ser 0 ou 1, não há nenhuma garantia.

Existem portas digitais com mais de 1 bit? Sim, claro, mas cada bit está conectado à uma linha externa, ou seja, é como se fossem várias portas de 1 bit em paralelo. De fato a porta paralela (hoje em dia muito raro de se encontrar nos PCs) funciona em parte dessa mesma forma e pode ser usada como uma porta de saída de 8 bits, ao gravar um byte os valores de cada bit afetam as linhas na saída.

No acrônimo GPIO do título desse artigo o termo "General" significa que é uma porta de uso geral, ou seja, não foi criada com uma função específica de entrada ou saída e pode ser configurada para uma dessas duas formas de funcionamento via software, ou seja, antes de começar a usar uma porta GPIO devemos configurar se ela vai se comportar como uma porta de entrada ou saída.

Já comentei que não podemos deixar um valor na faixa indeterminada para que possamos garantir a informação que vamos usar, observe a figura abaixo como foi conectado um interruptor e podemos ler o valor da porta para saber se ele está aberto ou fechado.


Observe que o interruptor pode estar aberto ou fechado, de um lado ele se liga a porta de entrada e de outro se liga ao VCC (tensão de trabalho, que geralmente é de 5v). Com esse esquema a tensão VCC é conectada à porta de entrada quando o interruptor é acionado e podemos ler o valor na respectiva porta. Tudo certo não é mesmo? Nem tanto... quando o interruptor está aberto o pino da porta de entrada não está ligado à nenhuma tensão e acaba ficando em um estado indeterminado, qualquer interferência poderia fazer com que uma tensão apareça nessa porta e faça um acionamento indevido.
Como solucionar essa situação? A resposta é simples, usando um resistor "pulldown", esse resistor é ligado entre a porta e o GND (Terra ou 0v) assim quando o interruptor está aberto garantimos o valor 0 e quando fechado boa parte da tensão do VCC passa até a porta de entrada pois o resistor "dificulta" a sua passagem para o GND, esse resistor força a porta a ficar no estado baixo. Se for interessante inverter a lógica, podemos usar um resistor "pullup" ligando a porta a um resistor e este no VCC, isso força a porta a ficar em nível alto, o interruptor se liga na porta e do outro lado no GND. Veja na imagem abaixo os dois exemplos.


Nos próximos artigos vamos ver como funcionam as portas analógicas.

segunda-feira, 4 de julho de 2016

Microcontroladores... esses pequenos computadores

O propósito desse post é comparar os microcontroladores que eu já tive a oportunidade de conhecer, claro que existem muitos outros no mercado e em um único post seria impossível esgotar todo o assunto.
Como eu disse na postagem anterior, um microcontrolador é um circuito integrado que possui um Microprocessador, alguma quantidade de memória e controles de I/O. É como se fosse um pequeno computador dentro de um único CI.
Minha primeira experiência foi com uma pequena placa chamada Basic Stamp II, ela vem equipada com um microcontrolador PIC16C56A-04 de 4 Mhz com um interpretador Basic interno e uma memória EEPROM serial que consegue armazenar até 80 instruções BASIC... só com isso já dá pra perceber que não dá pra fazer grandes coisas com ela, não é mesmo? O preço atual no site do fabricante é de US$ 29,00, é um valor muito alto para quem quer usar como hobby, a única vantagem é a fácil programação por meio da linguagem Basic. Essa placa pode ser reprogramada por um microcomputador a partir da sua IDE proprietária que faz a transferência usando a porta serial (outro problema nos dias atuais pois a maioria dos computadores só vem com USB, nada de Serial RS-232).
Depois eu comprei uma placa/laboratório para trabalhar com Microcontroladores PIC da Microchip, eles possuem uma linha muito grande e variada, em meus testes eu comprei vários chips do modelo mais comum deles, o PIC16F84A, por ser distribuído também no encapsulamento DIP ele é muito bem adaptado para ser usado em protoboards no laboratório.
Esses microcontroladores da linha PIC são construídos com a arquitetura RISC e o modelo de estrutura de memória Harvard, diferentemente dos PCs o código é armazenado em uma memória separada da memória que armazena os dados.
O tamanho da word de instruções é de 14 bits, pois esse é o tamanho de cada instrução, mas existem outros modelos com 12 bits e os mais novos com 32 bits.

Especificações dos modelos, todos funcionam em 20Mhz:

Microcontrolador Memória de programa RAM(bytes) EEPROM Preço no site
PIC16F84A 1792 bytes 68 bytes 64 bytes $3,11
PIC16F873 7 KB 198 bytes 128 bytes $4,57
PIC16F877 14 KB 368 bytes 256 bytes $5,39

Dentre as grandes vantagens desse tipo de microcontrolador estão o seu baixo custo e a possibilidade de reprogramação por meio da sua memória flash usando um protocolo serial, pode parecer pouco mas isso permite que se construa um "programmer" de baixo custo (isso é o circuito que liga o computador onde está o código escrito e o microcontrolador a ser programado) e também a possibilidade de se utilizar uma técnica chamada ICSP (In Circuit Serial Programming), como o próprio nome diz, você pode reprogramar o seu microcontrolador mesmo depois de já instalado em sua placa definitiva, basta que durante o projeto você deixe conectado os sinais necessário aos pinos que serão usados na reprogramação. Falarei mais sobre essa técnica em uma postagem futura.

Temos a linha da ATMEL que equipa as famosas placas Arduino, os primeiros modelos de placa eram equipados com o ATMEGA168 e encapsulamento DIP e vem espetados em um socket, esse chip pode ser substituído pelo ATMEGA328 (e foi nas placas mais novas) pois possui o mesmo tamanho e disposição de pinos, mas tem uma maior capacidade de armazenamento, veja na tabela adiante. As placas Arduino MEGA vinham equipadas com o ATMEGA1820, as mais modernas agora vêm equipadas com o ATMEGA2560 com maior poder de fogo, mas esses microcontroladores vem soldado na placa porque não tem encapsulamento DIP.
Existem muitos modelos diferentes de microcontroladores, placas e expansões usados pelo padrão Arduino, vamos deixar para falar disso depois, hoje vamos nos concentrar apenas nos microcontroladores, veja a comparação, todos funcionam em 16 MHz:
MicrocontroladorPinos I/OMemória
Digitalcom PWMAnalógicoFlashSRAMEEPROM
ATmega168146616 KB1 KB512 bytes
ATmega328P146632 KB2 KB1 KB
ATmega1280541516128 KB8 KB4 KB
ATmega2560541516256 KB8 KB4 KB

Note que temos memórias bem separadas aqui, a Flash contém o código que será executado, a SRAM contém a memória RAM de armazenamento temporário que vai apagar quando o microprocessador for desligado e a memória EEPROM que armazena dados e não se apaga quando desligado, essa última é muito usada para armazenar parâmetros de configuração do dispositivo, por exemplo, se você montou um dispositivo para ativar em certos dias da semana e horários, pode armazenar uma tabela com essa configuração nesse local e pode colocar na interface um modo de modificar a programação sem que você precise "compilar" e subir o programa com novos parâmetros para a memória Flash.
Os microcontroladores da ATMEL são tão completos que você pode construir um projeto Arduino sem precisar comprar uma placa Arduino, basta ter uma breadboard (aquela plaquinha de protótipo cheia de buraquinhos para encaixar as peças), um microcontrolador ATMEGA328 com encapsulamento DIP para encaixa na placa, um cristal de 16Mhz, dois capacitores cerâmicos de 22 pF, uma fonte de 5V e um adaptador USB -> Serial TTL (que depois da programação do microcontrolador pode ser retirado do projeto).

Espero ter ajudado a "esclariar" um pouco as ideias, ou então ter gerado dúvidas genuínas que os façam buscar por mais conhecimento.

Até a próxima !!!