EEPROM - Armazenando dados na memória não volátil do Arduino
Armazenando dados de forma não volátil no Arduino - EEPROM
A necessidade de se armazenar informações é algo bastante recorrente no desenvolvimento de projetos embarcados. Sejam elas um conjunto de variáveis para configurar o seu sistema, ou até mesmos dados que você queira visualizar após um intervalo de tempo, o armazenamento de informações é muito importante em praticamente todos os tipos de projetos. Porém nem sempre dispomos de um cartão SD, seja por limitações de custo ou até mesmo pinos de I/O, impossibilitando assim que a utilização de um cartão SD resolvesse o problema. Sabendo disso, neste tutorial, você aprenderá como utilizar a memória EEPROM existente nos microcontroladores Atmega das placas Arduino para armazenar dados permanentemente.
[toc]
Memória EEPROM
A memória EEPROM ou Electrically-Erasable Programmable Read-Only Memory, consiste em um modelo de memória onde diferente da memória RAM, podemos manter dados armazenados após desligarmos o nosso equipamento. Desta forma, é possível salvar informações que podem ser necessárias para o funcionamento do sistema após o seu desligamento, como por exemplo:
- Configurações
- Dados de difícil obtenção
- Dados estáticos
A utilização de memórias EEPROM, possibilitam com que o desenvolvedor seja capaz de armazenar diversas informações do sistema para uso posterior. Porém, este tipo de memória possui um ciclo muito pequeno de escritas, o que torna o seu uso viável apenas para o armazenamento de informações que serão pouco modificadas.
Memória eeprom i2c com encapsulamento dip.
O processo de leitura e escrita neste tipo de memória pode ser feito de duas formas:
- Paralelo: Cada byte é escrito de forma paralela na memória, sendo este escrito com base no endereço definido no barramento. Mais rápida, porém gasta uma maior quantidade de pinos para I/O
- Serial: Cada byte é escrito de forma serializada (normalmente utilizando o protocolo i2c) na memória eeprom. Mais lenta, porém gasta uma menor quantidade de pinos para I/O
Memória EEPROM no Arduino
Os microcontroladores ATmega possuem em sua arquitetura uma pequena memória eeprom, que pode ser utilizada como uma unidade de armazenamento. Cada microcontrolador possui uma de tamanho específico, segmentada em 1 byte por endereço. A lista abaixo ilustra a quantidade de memória disponível para a microcontroladores utilizados em plataformas como Arduino Nano, Arduino Uno e Arduino Mega:
- ATmega8,ATmega168 - 512 Bytes
- ATmega326 - 1024 Bytes
- ATmega1280, ATmega2560 - 4096 Bytes
Mãos à obra – Armazenando dados na memória EEPROM do Arduino
Neste projeto iremos apenas aprender a como manipular e realizar leituras e escritas na memória EEPROM do Arduino, desta forma iremos precisar apenas de um Arduino com algum dos microcontroladores citados acima.
Componentes Utilizados
Neste projeto iremos utilizar um Arduino Nano, porém praticamente todos os microcontroladores ATmega dispõem de uma memória eeprom nativa.
Programando
- Bibliotecas
Como iremos apenas aprender como armazenar e ler dados da memória EEPROM do Arduíno, iremos utilizar apenas a biblioteca EEPROM.h que já é nativa da ide que pode ser importada ao seu código da seguinte forma:
#include <EEPROM.h>
- Código Utilizado
Agora que temos o nosso sistema montado, e as bibliotecas adicionadas ao projeto, podemos partir para o código. Observem o código a seguir que utilizaremos como base para o nosso manipulador de memória.
#include <EEPROM.h> // Biblioteca para acesso e manipulação da EEPROM void setup() { Serial.begin(115200); // Inicialização da comunicação serial Serial.print("Espaco Disponivel em Bytes: "); // Mostra a quantidade de memória da EEPROM do seu microcontrolador Serial.println(EEPROM.length()); // Mostra a quantidade de memória da EEPROM do seu microcontrolador escreveByte(0,254); // Escreve o valor 255 na posição 0 da memória byte valor = leByte(0); // Lê o endereço 0 da memória ( onde escrevemos 255 ) Serial.print("Byte Armazenado: "); // Mostra o Byte Armazenado Serial.println(valor); // Mostra o Byte Armazenado escreveInt(1,2,1200); // Escreve o valor 1200 na EEPROM ( por ser um int de 2 bytes precisamos utilizar 2 endereços para armazenar) Serial.print ("Inteiro Armazenado: "); // Mostra o inteiro Armazenado Serial.println(lerInt(1,2)); // Mostra o inteiro Armazenado escreveString(3,"Vida de Silício"); // Escreve a String Vida de Silício na EEPROM, começando no endereço 3 Serial.println("String Armazenada: "+leString(3)); // Mostra a String armazenada } void loop(){ } byte leByte (int endereco1){ return EEPROM.read(endereco1); // Realizamosa leitura de 1 byte e retornamos } void escreveByte (int endereco1, byte valor){ // Escreve um byte na EEPROM no endereço especificado byte valorAtual = leByte(endereco1); // Lemos o byte que desejamos escrever if (valorAtual == valor){ // Se os valores forem iguais não precisamos escrever ( economia de ciclos de escrita ) return; } else { // Senão escrevemos o byte no endereço especificado na função EEPROM.write(endereco1,valor); // Escreve o byte no endereço especificado na função } } void escreveInt(int endereco1, int endereco2, int valor){ // Escreve um inteiro de 2 bytes na EEPROM int valorAtual = lerInt(endereco1,endereco2); // Lemos o valor inteiro da memória if (valorAtual == valor){ // Se o valor lido for igual ao que queremos escrever não é necessário escrever novamente return; } else{ // Caso contrário "quebramos nosso inteiro em 2 bytes e escrevemos cada byte em uma posição da memória byte primeiroByte = valor&0xff; //Executamos a operação AND de 255 com todo o valor, o que mantém apenas o primeiro byte byte segundoByte = (valor >> 8) &0xff; // Realizamos um deslocamento de 8 bits para a direita e novamente executamos um AND com o valor 255, o que retorna apenas o byte desejado EEPROM.write(endereco1,primeiroByte); // Copiamos o primeiro byte para o endereço 1 EEPROM.write(endereco2,segundoByte); // Copiamos o segundo byte para o endereço 2 } } int lerInt(int endereco1, int endereco2){ // Le o int armazenado em dois endereços de memória int valor = 0; // Inicializamos nosso retorno byte primeiroByte = EEPROM.read(endereco1); // Leitura do primeiro byte armazenado no endereço 1 byte segundoByte = EEPROM.read(endereco2); // Leitura do segundo byte armazenado no endereço 2 valor = (segundoByte << 8) + primeiroByte; // Deslocamos o segundo byte 8 vezes para a esquerda ( formando o byte mais significativo ) e realizamos a soma com o primeiro byte ( menos significativo ) return valor; // Retornamos o valor da leitura } void escreveString(int enderecoBase, String mensagem){ // Salva a string nos endereços de forma sequencial if (mensagem.length()>EEPROM.length() || (enderecoBase+mensagem.length()) >EEPROM.length() ){ // verificamos se a string cabe na memória a partir do endereço desejado Serial.println ("A sua String não cabe na EEPROM"); // Caso não caiba mensagem de erro é mostrada } else{ // Caso seja possível armazenar for (int i = 0; i<mensagem.length(); i++){ EEPROM.write(enderecoBase,mensagem[i]); // Escrevemos cada byte da string de forma sequencial na memória enderecoBase++; // Deslocamos endereço base em uma posição a cada byte salvo } EEPROM.write(enderecoBase,'\0'); // Salvamos marcador de fim da string } } String leString(int enderecoBase){ String mensagem=""; if (enderecoBase>EEPROM.length()){ // Se o endereço base for maior que o espaço de endereçamento da EEPROM retornamos uma string vazia return mensagem; } else { // Caso contrário, lemos byte a byte de cada endereço e montamos uma nova String char pos; do{ pos = EEPROM.read(enderecoBase); // Leitura do byte com base na posição atual enderecoBase++; // A cada leitura incrementamos a posição a ser lida mensagem = mensagem + pos; // Montamos string de saídaa } while (pos != '\0'); // Fazemos isso até encontrar o marcador de fim de string } return mensagem; // Retorno da mensagem }
Colocando pra funcionar
Se nada tiver sido modificado no código e sua EEPROM ainda possuir ciclos de escrita, a seguinte mensagem será apresentada no monitor serial:
Entendendo a Fundo
Software
- Incluindo bibliotecas necessárias
Para este sistema, iremos precisar apenas da biblioteca EEPROM.h que já é nativa do Arduíno e será utilizada como interface entre a EEPROM e o nosso código, desta forma ela pode ser adicionada da seguinte forma:
#include <EEPROM.h>
- Função Setup
Em nossa função setup, iremos basicamente escrever e ler as variáveis que desejamos armazenar na EEPROM, foram definidos um conjunto de 6 funções, sendo três para escrita e três para leitura de tipos de dados normalmente utilizados, sendo eles:
- Int
- Byte
- String
Sendo assim, no setup iremos apenas utilizar estas funções, da seguinte forma:
- Função escreve byte
Escreve um valor em byte no endereço especificado, neste exemplo estamos escrevendo o valor 254 no endereço 0 da memória.
escreveByte(0,254); // Escreve o valor 255 na posição 0 da memória
- Função lê byte
Realiza a leitura de um único byte no endereço especificado pelo usuário, neste exemplo estamos lendo o endereço 0.
byte valor = leByte(0);
- Função escreve int
Escreve um valor inteiro composto por 2 bytes, em duas posições quaisquer da eeprom, neste exemplo estamos escrevendo o valor 1200 utilizando os endereços 1 e 2.
escreveInt(1,2,1200);
- Função lê int
Realiza a leitura de dois endereços especificados pelo usuário, reconstruindo o valor inteiro que elas representam, neste exemplo estamos lendo os endereços 1 e 2 da memória.
Serial.println(lerInt(1,2));
- Função escreve string
Escreve uma determinada string de forma sequencial na EEPROM, neste exemplo estamos utilizando um total de 15 endereços (começando do endereço 3) para escrever a string "Vida de Silício" em nossa memória.
escreveString(3,"Vida de Silício");
- Função lê string
Dado um endereço base fornecido, esta função lê sequencialmente toda a string armazenada.
leString(3);
Entendendo cada função implementada
Cada função implementada possui um grau complexidade devido a realização de operações lógicas para quebra de bytes e armazenamento sequencial, desta forma iremos mostrar a forma como cada função é capaz de salvar e recuperar seus respectivos tipos de dados. Porém antes vamos entender um pouco a forma como a nossa memoria funciona.
Imagine a sua memória como um um conjunto de blocos onde podemos armazenar valores em um intervalo de 0 até 255, e cada um desses intervalos está associado a um endereço, sendo assim, podemos imaginar a nossa memória da seguinte forma: Com essa estrutura de memória podemos salvar qualquer tipo de informação, desde que o espaço seja suficientemente grande para armazenar todos os valores.
- Função escreveByte
A função escreveByte recebe como argumentos o endereço e o valor a ser escrito naquela posição, verificando apenas se o byte que desejamos escrever já não está lá, desta forma economizamos uma escrita que seria feita desnecessariamente, prologando assim a vida útil de nossa memória.
void escreveByte (int endereco1, byte valor){ byte valorAtual = leByte(endereco1); if (valorAtual == valor){ return; } else { EEPROM.write(endereco1,valor); } }
Estruturalmente, podemos dizer que esta função executa a seguinte operação:
- Função leByte
Já a função leByte, basicamente realiza a leitura do endereço especificado em seu argumento, retornando assim o valor que está armazenado naquele endereço.
byte leByte (int endereco1){ return EEPROM.read(endereco1); }
Utilizando o nosso modelo de memória, podemos dizer que estamos realizando a seguinte operação:
- Função escreveInt
Nos microcontroladores ATmega, uma variável do tipo int, é representada por um total de 2 bytes, sendo estes divididos entre mais significativos (HB) e menos significativos (LB), como a nossa memória permite apenas o armazenamento de 1 byte por endereço. Sabendo disso, é necessário que a nossa função seja capaz de "quebrar" o nosso valor inteiro de 2 bytes, em duas variáveis de 1 byte cada, para que assim seja possível armazenar esta informação na memória. Para que isso seja feito, iremos utilizar dois tipos de operações lógicas existente em praticamente todas as arquiteturas de computadores, que são as operações rigth shift e and bitwise.
void escreveInt(int endereco1, int endereco2, int valor){ int valorAtual = lerInt(endereco1,endereco2); if (valorAtual == valor){ return; } else{ byte primeiroByte = valor&0xff; byte segundoByte = (valor >> 8) &0xff; EEPROM.write(endereco1,primeiroByte); EEPROM.write(endereco2,segundoByte); } }
Sabendo disso o algoritmo funciona da seguinte forma:
- Inicialmente verificamos se o valor que desejamos inserir é igual ao que está na memória ( se for economizamos duas escritas na memória )
- Caso não seja executamos a seguinte operação:
- Dado o nosso valor de exemplo 1001, serão executadas as seguintes operações:
- Aplicamos uma operação AND bit a bit sob o valor que desejamos quebrar com o número 255, desta forma iremos preservar apenas os bits da primeira cadeia de byte que desejamos armazenar. A figura abaixo ilustra como o processo é feito e o resultado obtido através da operação realizada.
- Para o segundo byte, realizaremos o mesmo processo do passo 2, porém ao invés apenas aplicar a operação lógica AND, iremos antes deslocar os bits que estão na camada superior. Para que dessa forma, cheguem a posição dos bits menos significativos para a aplicação da máscara.
- Por fim, com os bytes separados, a função salva cada um deles no endereço especificado como mostra a figura abaixo:
- Dado o nosso valor de exemplo 1001, serão executadas as seguintes operações:
- Função leInt
O processo de leitura segue praticamente a lógica inversa do processo de escrita, onde iremos ler cada byte e montar o nosso valor da seguinte forma:
- Relizamos uma leitura do endereço de valor mais significativo, este valor é deslocado 8 bits a esquerda para que volte a sua posição de bit mais significativo.
- Realizamos uma leitura do endereço de valor menos significativo, este valor é somado ao valor deslocado para que volte a posição de bit menos significativo.
- Temos o nosso valor montado novamente.
int lerInt(int endereco1, int endereco2){ int valor = 0; byte primeiroByte = EEPROM.read(endereco1); byte segundoByte = EEPROM.read(endereco2); valor = (segundoByte << 8) + primeiroByte; return valor; }
- Função escreveString
A função escreve string por sua vez, não utiliza de recursos de deslocamento de bits, devido ao fato de que cada caractere, é um único byte. Ou seja, uma string nada mais é do que um vetor de bytes alocados sequencialmente. Sabendo disso, o nosso algoritmo de salvar uma string na memória segue a seguinte lógica:
- Dado um endereço base, e o tamanho da string verificamos se é possível o armazenamento ou não.
- Caso não seja possível, o valor não é salvo.
- Caso seja possível, a string é alocada sequencialmente na memória começando com o endereço base e terminando sempre com um ''\0''
void escreveString(int enderecoBase, String mensagem){ if (mensagem.length()>EEPROM.length() || (enderecoBase+mensagem.length()) >EEPROM.length() ){ Serial.println ("A sua String não cabe na EEPROM"); } else{ for (int i = 0; i<mensagem.length(); i++){ EEPROM.write(enderecoBase,mensagem[i]); enderecoBase++; } EEPROM.write(enderecoBase,'\0'); } }
- Função leString
A função leString por sua vez, realiza praticamente o mesmo processo que a leitura, porém ao invés de armazenar os bytes como na função escreveString, ela utiliza a função read, para ler cada byte armazenado sequencialmente. Desta forma podemos dizer que o algoritmo funciona da seguinte forma:
- Com base no endereço inicial, a função lê cada byte lido, até que o caractere de fim de texto '\0', seja encontrado. Quando encontrado uma string montada é retornada pela função.
String leString(int enderecoBase){ String mensagem=""; if (enderecoBase>EEPROM.length()){ return mensagem; } else { char pos; do{ pos = EEPROM.read(enderecoBase); enderecoBase++; mensagem = mensagem + pos; } while (pos != '\0'); } return mensagem; }
Desafio
Agora que sabemos como manipular a memória EEPROM do nosso Arduino, tente adicionar esta funcionalidade a algum projeto que seja necessária a configuração de uma variável em tempo real. Um exemplo de sistema desse tipo são os dataloggers, onde precisamos configurar informações como tempo de leitura e configuração de sensores.
Considerações finais
Este tutorial, teve como objetivo mostrar como manipular a memória EEPROM, interna do seu Arduino, funcionando como uma pequena unidade de armazenamento para informações importantes. Espero que tenham gostado do conteúdo apresentado, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.
Shield Ethernet W5100 - Criando um Servidor Web com Arduino
Shield Ethernet W5100 - Primeiros passos na criação de um Servidor Web com Arduino
Em uma das nossas publicações anteriores ensinamos como você deve proceder para criar um Servidor Web com o NodeMCU. Neste tutorial, iremos utilizar um Shield Ethernet W5100 para criar um Servidor Web que terá como função fornecer uma página web contendo informações enviadas pelo Arduino UNO.

[toc]
O que é um Servidor Web?
Ao navegarmos pelo gigante universo de possibilidades da internet, podemos não nos dar conta do que existe por trás disso tudo.
A internet é uma união de redes de computadores em nível mundial conversando entre si através de um conjunto próprio de protocolos de comunicação, como por exemplo, o TCP/IP, que por sua vez, consiste em um protocolo para transmissão de informações orientado à conexão, ou seja, cuja função consiste em permitir que as maquinas se comuniquem e gerenciem o estado atual da transmissão.
- Os Servidores
Um dos protagonistas desse universo são os servidores. A grosso modo, esses servidores são computadores responsáveis por fornecer e receber dados dos diversos clientes, atuando como centralizadores de informação.

Indo um pouco a fundo, um servidor consiste em um software dentro um computador centralizador. Através de uma rede particular ou da internet, esse servidor pode receber dados de clientes bem como fornecê-los.
O estabelecimento das relações entre o conjunto Servidor/Cliente é baseado em um sistema de recebimento, processamento e resposta, no qual, o servidor recebe, processa e responde a requisições feitas por um Cliente através de algum protocolo de comunicação.
- O HTTP - Protocolo de Transferência de Hipertexto
Um dos principais exemplos da relação Servidor/Cliente é a relação entre os computadores que atuam como servidores hospedando sites e os navegadores que utilizamos em nossos computadores ou celulares, os clientes. Neste tipo de relação, utiliza-se para estabelecer a comunicação, o procotolo o HTTP (Hypertext Transfer Protocol), o qual, é responsável pelo tratamento dos pedidos e respostas entre cliente e servidor na World Wide Web ou em uma rede local. Nesse contexto, chamamos os servidores de Servidores Web.

- HTML - Linguagem de Marcação de Hipertexto
As informações que o Servidor Web envia para seu navegador a partir de uma requisição HTTP feita pelo mesmo, pode ocorrer em alguns determinados formatos que precisarão ser interpretados. Um desses formatos é o HTML (HyperText Markup Language), que por sua vez, é uma linguagem utilizada na construção de páginas na Web.

O Shield Ethernet W5100
Como sabemos, os shields compatíveis com o Arduino UNO são placas de circuito que podem ser conectadas sobre o mesmo, encaixando-se perfeitamente, com o intuito de expandir suas capacidades em determinada vertente.
Neste tutorial, apresentamos o Shield Ethernet W5100, que por sua vez, consiste em um shield dotado de dois módulos, um módulo Ethernet que irá permitir a conexão do Arduino UNO, em um primeiro momento, com uma rede local e um módulo para cartão SD.
Sendo assim, perceba que é perfeitamente possível utilizar este módulo somente para ler/escrever dados em um cartão de memória ou apenas para conectar o Arduino UNO a uma rede local.

Neste tutorial iremos utilizar apenas o módulo Ethernet do shield em questão, pois, iremos elaborar uma pagina simples para ser apresentada ao usuário através do navegador, no entanto, o módulo de cartão SD é muito útil para conter arquivos necessários para a construção de uma página mais rica em informações, como por exemplo, imagens.
Mãos à obra - Criando um Servidor Web com o Arduino UNO e o Shield Ethernet W5100
Nesta seção iremos demonstrar todos os passos que você deve seguir para aprender a criar um Servidor Web.
Componentes necessários
Para reproduzir este projeto, você irá precisar dos seguintes componentes:
Montando o projeto

Gostaríamos de sugerir que você tenha bastante cuidado no momento em que for encaixar o Shield Ethernet W5100 no Arduino UNO, pois, além da possibilidade de entortar os pinos do shield, você também pode se machucar.
Lembre-se que o shield ethernet W5100 possui uma série de pinos em sua parte inferior, tanto nas laterais como em sua parte dianteira, portanto, antes de pressionar o mesmo sobre o Arduino UNO, certifique-se de que os pinos estejam levemente posicionados em suas respectivas entradas para que então você possa ir realizando o encaixe lentamente.
Realizando as conexões
Para reproduzir este projeto, garanta que o seu Shield Ethernet W5100 esteja ligado corretamente a uma das portas LAN presentes no seu modem ou roteador.
Programando
Este programa foi elaborado a partir do código-exemplo da biblioteca Ethernet.h denominado WebServer.
Antes de utilizar este código, leia a seção Entendendo a fundo para adaptar os trechos necessários para o funcionamento da sua aplicação.
#include <SPI.h> #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 25, 16); EthernetServer server(80); void setup() { Ethernet.begin(mac, ip); server.begin(); } void loop() { EthernetClient client = server.available(); if (client) { boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE html>"); client.println("<html>"); client.println("<head>"); client.println("<title>Servidor Web VDS</title>"); client.println("</head>"); client.println("<body>"); client.println("<h1>Meu primeiro Servidor Web</h1>"); client.println("<p>Esperamos que voce tenha gostado deste tutorial</p>"); client.println("</body>"); client.println("</html>"); break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } delay(1); client.stop(); } }
Colocando para funcionar
Veja como ficou nosso primeiro Servidor Web.

Entendendo a fundo
Software
- Incluindo as bibliotecas a serem utilizadas no projeto
Inicialmente, observe que foi necessário incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca SPI.h é a responsável pela comunicação dos módulos do Shield Ethernet W5100 com o Arduino UNO utilizando o protocolo SPI e a biblioteca Ethernet.h atua possibilitando a conexão do conjunto, em um primeiro momento, com uma rede local.
#include <SPI.h> #include <Ethernet.h>
- Definindo o endereço MAC do Arduino UNO
O próximo passo consiste em definir o endereço MAC que será atribuído ao Arduino UNO.
Na prática, o endereço MAC pode ser qualquer um, desde que seja único na rede. Como sugestão, copie a sentença abaixo.
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
- Definindo o endereço IP do Arduino UNO
Além do endereço MAC definido anteriormente, torna-se necessário definir um endereço IP para o nosso Arduino UNO. Isso é imprescindível para que seja possível estabelecer a conexão entre o mesmo e a rede.
Este endereço deve estar disponível na sua rede local para que possa ser utilizado
Existem várias maneiras de encontrar um endereço válido na sua rede local, de modo que, demonstraremos uma forma bastante simples de realizar este procedimento, confira abaixo:
- Acesse um computador que esteja conectado na sua rede local
- Abra o Prompt de Comando do Windows (supondo que o sistema operacional seja Windows)
- Digite ipconfig
Neste momento, um conjunto de informações será disponibilizado, no entanto, o dado que requer sua atenção é justamente o endereço IP da máquina que você está utilizando (ele estará apresentado pelo nome IPV4).
Primeiramente, repare que o endereço IP destacado possui quatro partes separadas por pontos. Para encontrarmos um possível endereço disponível em nossa rede local, basta modificarmos a última parte do endereço encontrado, como por exemplo, o endereço 192.168.25.16 . Geralmente, este procedimento é suficiente para encontrar possíveis endereços disponíveis em redes locais pequenas, como as das nossas casas.
IPAddress ip(192, 168, 25, 16);
- Criando o objeto server
Neste momento, cria-se um objeto chamado server, que por sua vez, será responsável por representar o Servidor Web no código do Arduino UNO.
Note que ao criarmos o objeto, passamos o número 80 como parâmetro, pois estamos determinando a porta que o Servidor Web utilizará para enviar as páginas web que serão criadas posteriormente.
A título de curiosidade, quando digitamos o endereço de algum site no navegador, ele automaticamente procura a porta 80 do servidor no qual está se conectando, de modo que, se o serviço responsável por disponibilizar as páginas da web para o cliente estiver em outra porta, devemos especificar esta no endereço do site citado, por exemplo: www.exemplo.com.br:1234
EthernetServer server(80);
- Iniciando a comunicação com a rede local e o Servidor Web
Na função setup() iniciamos a conexão com a rede local através da função Ethernet.begin() (passando como parâmetro os endereços MAC e IP definidos anteriormente) e também iniciamos o Servidor Web por meio da sentença server.begin() (lembre-se que server é o objeto criado para representar o Servidor Web no código).
Ethernet.begin(mac, ip); server.begin();
Veja como ficou nossa função setup():
void setup() { Ethernet.begin(mac, ip); server.begin(); }
- Respondendo as requisições de um navegador
Verificando se existe requisição de conexão
Primeiramente, na função loop(), temos a sentença server.available() que verifica se existe tem algum cliente tentando fazer uma conexão. Como dito anteriormente, vamos chamar de cliente, o navegador que está tentando fazer a conexão com o Servidor Web através do endereço IP do mesmo. Repare que foi criada uma variável para conter o valor retornado pela função server.available().
EthernetClient client = server.available();
Em seguida, temos uma função if() cujo conteúdo será executado apenas no caso de termos um cliente tentando se conectar ao Servidor Web criado e iniciado anteriormente.
if (client) { ***** Conteúdo da função if() ***** }
Supondo que temos um cliente tentando se conectar com o nosso Servidor Web, primeira sentença do conteúdo da função if() apresentada anteriormente consiste na declaração de uma variável de controle booleana que será utilizada na leitura da requisição feita pelo navegador.
boolean currentLineIsBlank = true;
Posteriormente, temos uma função while(), que por sua vez, fará com que a execução do programa fique restrita ao seu conteúdo enquanto o parâmetro passado para mesma for verdadeiro. O parâmetro citado corresponde à sentença client.connected(), responsável por retornar verdadeiro ou falso, caso o cliente esteja conectado ou não com o Servidor Web, respectivamente.
Portanto, enquanto o cliente estiver conectado com o nosso servidor, o programa ficará preso na função while().
while (client.connected()) { ***** Conteúdo da função while() }
Imagine que a conexão do cliente (navegador) com o nosso Servidor Web tenha sido estabelecida. Neste momento o programa irá se preparar para receber a requisição feita pelo cliente, que por sua vez, é dada em forma de um grande texto, logo, utilizamos a função if() juntamente com a sentença client.available() para verificar se ainda existe alguma informação proveniente do navegador para ser lida. Caso exista, o conteúdo desta função será executado.
if (client.available()) { ***** Conteúdo da função if() ***** }
Lendo a requisição do cliente
Caso exista alguma informação para ser lida, utilizamos a sentença client.read() para ler caractere por caractere do grande texto de requisição citado anteriormente, de modo que, a cada passagem por esta sentença (lembre-se que isso é feito de maneira cíclica), um novo caractere será armazenado na variável do tipo char c.
char c = client.read();
Após preenchermos a variável c com um determinado caractere da requisição, fazemos uma série de comparações deste com alguns parâmetros específicos para saber se o Arduino UNO recebeu o pacote de informações inteiro ou não.
O objetivo aqui não é entender tudo que esta vindo do cliente mas simplesmente entender que existe uma solicitação acontecendo e que após o término da mesma, vamos devolver como resposta uma pagina da web, sendo assim, devemos esperar que venha o texto completo de solicitação, até a ultima linha.
Caso a condição desta primeira função de tratamento da variável c seja verdadeira, quer dizer que recebemos o pacote completo e que o conteúdo desta função if() será executado.
if (c == '\n' && currentLineIsBlank) { ***** Conteúdo da função if() ***** }
Enviando informações para o navegador
Neste momento, nós iremos criar as funções necessárias para que o nosso Arduino UNO envie uma página da web como resposta à solicitação do navegador. As instruções que utilizaremos para enviar informações ao navegador serão baseadas na sentença client.println().
Primeiramente, enviamos um cabeçalho padrão informando ao navegador que estamos mandando uma página da web utilizando o protocolo HTTP, feita utilizando a linguagem HTML.
client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println();
- Usando HTML para montar a página web
HTML é uma linguagem, porém, não exatamente uma linguagem de programação mas sim uma linguagem de marcação, ou seja, através desta nós enviamos comandos para um navegador, que por sua vez, irão orientar o mesmo na montagem da pagina.
Uso de tags em HTML
Em um primeiro momento, nós devemos saber que a linguagem HTML é composta por elementos que iremos chamar de tags. Estes consistem em comandos que são enviados para o navegador para informarmos alguma coisa ao mesmo, para pedirmos que ele mostre algo, para definirmos o formato de fonte que queremos, se é negrito, qual cor, entre outros.
Todos as tags em HTML são declaradas entre os sinais de maior e menor <nome_da_tag>. Torna-se importante ressaltar que muitas tags possuem uma abertura e um fechamento (este possui o mesmo nome da tag, porém, com uma "/" antes do respectivo nome, por exemplo, </nome_da_tag>), de modo que, tudo o que está entre a abertura e o fechamento de uma determinada tag será afetado pelo comando gerado pela função da mesma.
A estrutura da página em HTML
Vamos começar a entender a estrutura de uma pagina em HTML. Primeiramente, qualquer pagina em HTML precisa possuir a tag <html> cuja função é indicar para o navegador que estamos começando um bloco de programação utilizando a linguagem HTML (opcionalmente podemos utilizar também a tag <!DOCTYPE HTML> para informar o tipo documento, de modo que, se não colocarmos isto, o navegador entenderá da mesma forma) e o fechamento da mesma </html>, que por sua vez, indica o fim do bloco citado.
client.println("<!DOCTYPE HTML>"); client.println("<html>"); . . ***** Conteúdo da página ***** . . client.println("</html>");
Dentro do bloco citado anteriormente, temos o conteúdo da página que queremos enviar para o navegador, de modo que, neste, devemos ter pelo menos dois blocos, um responsável pelas informações gerais do documento, limitado pelo uso do par <head></head> e o outro, por sua vez, deve conter o corpo da página e está entre as tags <body> e </body>.
client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); . . ***** Bloco 1 ***** . . client.println("</head>"); client.println("<body>"); . . ***** Bloco 2 ***** . . client.println("</body>"); client.println("</html>");
Definido o título para a página
Neste momento, vamos utilizar apenas uma tag dentro do bloco 1, denominada <title>, cuja função consistirá em definir um título para a página (este título aparecerá na aba do navegador). Para executarmos a ação proposta, devemos colocar o título desejado entre o par <title></title>.
client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); client.println("<title>Servidor Web VDS</title>"); client.println("</head>"); client.println("<body>"); . . ***** Bloco 2 ***** . . client.println("</body>"); client.println("</html>");
Veja como ficou o título da nossa página:

Escrevendo o corpo da página web
Quanto ao corpo da página, a primeira coisa que faremos será colocar um título visível na própria página. Para realizar este procedimento, utilizaremos a tag <h1>, que por sua vez, consiste em uma tag de cabeçalho, cuja função consiste em apresentar um determinado texto em um modelo predefinido. Lembre-se que os textos que tiverem fora do par <h1></h1> serão apresentados fora do padrão citado.
client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); client.println("<title>Servidor Web VDS</title>"); client.println("</head>"); client.println("<body>"); client.println("<h1>Meu primeiro Servidor Web</h1>"); client.println("</body>"); client.println("</html>");
Veja como está nossa página até agora

Opções de cabeçalhos
Devemos ressaltar que não há nenhum problema em utilizar vários cabeçalhos iguais, portanto, você pode tranquilamente criar vários textos utilizando o cabeçalho h1, pois, ele apenas indica uma certa formatação. Além do cabeçalho que já utilizamos, temos também os cabeçalhos h2,h3,h4,h5,h6, os quais, nesta ordem, possuem fontes cada vez menores.
Escrevendo um texto simples
Por fim, utilizaremos uma tag voltada para a escrita de textos simples. Esta pode ser referenciada no código pelo par <p></p>.
client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); client.println("<title>Servidor Web VDS</title>"); client.println("</head>"); client.println("<body>"); client.println("<h1>Meu primeiro Servidor Web</h1>"); client.println("<p>Esperamos que voce tenha gostado deste tutorial</p>"); client.println("</body>"); client.println("</html>");
Veja nosso resultado final:

- Verificando se a requisição foi finalizada
Após o desenvolvimento da nossa página, saímos da função if() utilizada para saber se a requisição foi finalizada e encontramos outras duas funções if() que cumprem o teste das condições não contempladas pela primeira, ou seja, atuam no tratamento da variável c enquanto a requisição não foi finalizada.
if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; }
Por fim utilizamos a função delay() para garantir que o navegador receba esta informação que estamos mandando e também a sentença client.stop() para parar a conexão.
delay(1); client.stop();
Considerações finais
Neste tutorial, demonstramos como você pode dar os primeiros passos na criação de um Servidor Web utilizando um Arduino UNO e um Shield Ethernet W5100. Esta foi apenas a primeira parte de uma série de artigos sobre a criação de Servidores Web, portanto, esperamos que continue nos acompanhando e sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.
Display LCD 20x4 e 16x2 com Adaptador I2C
Display LCD 20x4 e LCD 16x2 com Adaptador I2C – Utilizando o display com Arduino
No tutorial sobre a utilização de um display lcd 16x2 com Arduino aprendemos a importância dos displays e como usar um LCD de caracteres, em especial o 16x2. Apesar de esse LCD ser prático e simples, ele possui um problema, uma grande demanda por ligações. Para resolver isso, podemos usar um módulo adaptador I2C que facilita ainda mais o uso desse tipo de recurso. Nesse tutorial iremos aprender a usar o Display LCD 20x4 com Adaptador I2C junto a um Arduino.
O uso tanto do display LCD 16x2 tanto do display LCD 20x4 é muito semelhante, a diferença entre eles é o numero de caracteres que dispõem na tela. Como falamos sobre o modelo 16x2 no último tutorial, iremos aproveitar a oportunidade para mostrar um pouco mais sobre o modelo 20x4. Caso você tenha em suas mão o 16x2, você poderá facilmente adaptar o programa usado nesse tutorial para você.
[toc]
Porque usar comunicação I2C para controlar seu LCD?

Na figura acima, percebemos a existência de uma grande quantidade de contatos para realização do seu acionamento. Para facilitar o seu uso, iremos trabalhar com o adaptador I2C para display LCD.
Para usar esse LCD diretamente no Arduino, você irá precisa, além das ligações de alimentação, de 6 pinos: RS, EN, D7, D6, D5, e D4 para que seu LCD converse com seu Arduino. Se você estiver trabalhando com um projeto mais complexo, talvez você não terá tantos pinos disponíveis no seu Arduino para seu LCD da forma usual.
Com o módulo de interface I2C, você precisará de apenas 2 pinos (I2C) para imprimir as informações que deseja em seu LCD. Se você já tiver usando outros componentes I2C em seu projeto, esse pino não precisará usar mais nenhuma porta, visto que ele poderá usar os mesmo pinos já usado para o outro dispositivo I2C.
Adaptador I2C para Display LCD 20x4 e 16x2

Para que seja possível a comunicação entre o Arduino e o LCD, precisaremos de um adaptador I2C. Esse adaptador nada mais é que um conversor cuja função consiste em manipular os contatos do LCD, de modo que, após este processo, teremos apenas 2 contatos para realizar a comunicação com uma placa Arduino através do protocolo I2C.
Ele conta com o chip PCF8574T ou PCF8574AT que é responsável por essa interface . Você pode encontrar vários modelos de módulos ligeiramente diferentes.
Em geral eles possuem o seguinte formato:

Como você pode ver na imagem, a maioria dos módulos de interface I2C para LCD possuem:
- Pinos para conexão com o Display (16 pinos);
- Pinos de Alimentação do Módulo (GND e VCC);
- Pinos de comunicação I2C (SDA e SCL);
- Trimpot para ajuste de contraste da tela;
- Jumper para ligar e desligar a luz de fundo (Backlight);
- Led indicador de módulo ligado.
- Chip de Interface (PCF8574T ou PCF8574AT )
Endereço do módulo I2C
Para alguns modelos ainda é possível configurar o endereço do módulo I2C através de A0, A1 e A2. Abaixo você pode conferir a tabela de endereços possíveis para cada um dos chips (PCF8574T ou PCF8574AT ):

A0, A1 e A2 são portas do nosso Chip:

Que em geral vem ligados a alimentação do módulo (VCC):

Quando conectamos o ponto 1 com 1, 2 com 2 ou 3 com 3, estamos colocando um nivel lógico baixo em A0, A1 ou A2 respectivamente. Na figura anterior, os pinos A0, A1 e A2 estão conectados ao chip do módulo. Veja que segundo esse esquemático, estamos com 5V em cada um dos 3 pinos. Ou seja, nosso endereço será 0x27 caso o chip seja o PCF8574T ou 0x3F caso o chip seja o PCF8574AT.
Para alterar o endereço podemos colocar um ponto de solda para conectar os pinos A0, A1 ou A2 ao GND para as placas que tenha essa opção:

Para conectar os pinos A0, A1 ou A2 ao GND, você precisa pode usar solda de estanho para ligar o ponto de baixo com o de cima, tal como na figura a seguir:

Display LCD 20x4 com adaptador I2C
Para o nosso tutorial, iremos usar um LCD que já possui o adaptador soldado ao módulo display. Para o display que usaremos não temos a opção de mudança de endereço:

Veja em detalhes o módulo I2C usado:
Repare que ele não tem a opção de mudança de endereço. O chip dele é o PCF8574T, ou seja, iremos usar o endereço 0x27.
Display LCD 16x2 com adaptador I2C
Você também pode usar a versão do Display LCD 16x2 com adaptador I2C. A maior diferença é a quantidade de caracteres. Explicaremos mais a frente como adaptar o programa que usamos nesse tutorial para o display LCD 16x2.
O endereçamento funcionará da mesma forma que o explicado anteriormente. Verifique o modelo do seu adaptador para descobrir o endereço do mesmo.

Mãos à obra – Imprimindo informações no display LCD 20x4 I2C
Componentes utilizados
Caso tenha um LCD 16x2 ou 20x4 e queira adapta-lo, basta adquirir o Módulo i2C separado. Módulo I2C para Display LCD compativel com 16x02 e 20x4
Montando o projeto
Na figura abaixo, o leitor poderá conferir como foi realizada a montagem do projeto apresentado neste tutorial. Lembre-se de montar o projeto com o seu Arduino desligado.


Veja como ficou o nosso:
Programando
Antes de adentrarmos na apresentação do código, disponibilizamos uma seção para ajudar aqueles que são iniciantes no assunto. Sinta-se livre para prosseguir caso você já tem domínio da IDE do Arduino.
Conectando o Arduino ao computador
Primeiramente, conecte seu Arduino ao computador e abra a IDE Arduino. Em seguida, é necessário selecionar a porta COM na qual o Arduino está conectado (este procedimento pode ser feito clicando no menu Ferramentas (tools) e em seguida escolhendo-se a porta correspondente no submenu Porta (port). Neste caso, a porta na qual está o Arduino é apresentada da seguinte maneira: COM3 (Arduino Micro).
Por fim, garanta também que o tipo de placa apropriado esteja selecionado (isso pode ser feito acessando o menu Ferramentas (tools) e o submenu Placa (board)).
- Biblioteca
Para desenvolver o projeto proposto com o Display LCD I2C 20X4 utilizou-se uma biblioteca capaz de atuar sobre o protocolo I2C para facilitar os processos de endereçamento e troca de dados que fazem parte do funcionamento do protocolo citado. Esta biblioteca pode ser encontrada aqui.
Adquirindo e instalando a biblioteca que será utilizada
Após a realização do download dos arquivos compactados no formato ZIP, abra a IDE do Arduino, selecione o menu Sketch, o submenu Incluir Bilioteca e por fim, basta clicar na opção Adicionar biblioteca .ZIP (Add ZIP Library) e encontrar o arquivo que acabou de ser baixado.
Uma outra forma de fazer isso é extrair o conteúdo do arquivo ZIP dentro da pasta Libraries (onde foi instalada a IDE do Arduino).
– Código do projeto
Segue o código a ser utilizado no Arduino para imprimir informações no Display LCD I2C 20x4.
#include <Wire.h> #include <LiquidCrystal_I2C.h> // Inicializa o display no endereco 0x27 LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE); void setup() { lcd.begin (20,4); } void loop() { lcd.setCursor(0,0); lcd.print("********************"); lcd.setCursor(9,1); lcd.print("VIDA"); lcd.setCursor(5,2); lcd.print("DE SILICIO"); lcd.setCursor(0,3); lcd.print("********************"); }
Entendendo a fundo
Software
- Incluindo as bibliotecas
Inicialmente, observe que foi necessário incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca wire.h é a responsável pela comunicação utilizando o protocolo I2C enquanto a biblioteca LiquidCrystal_I2C.h atua sobre a biblioteca wire.h simplificando o processo de comunicação através do protocolo citado, para que assim, o usuário possa utilizar o Display LCD I2C 20x4 de maneira mais fácil.
#include <Wire.h> #include <LiquidCrystal_I2C.h>
- Criando o objeto lcd
Em seguida, cria-se um objeto que será utilizado posteriormente para representar o Display LCD I2C 20x4 no código.
Lembre-se: lcd é apenas um nome, sendo assim, é importante ressaltar que este objeto poderia ser chamado por qualquer outro nome, como por exemplo, display.
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);
Essa função é padrão tanto para o LCD 20x4 como para o 16x2. Nela definimos o endereço do adaptador, que para o nosso equivale sempre 0x27.
Além do endereço, definimos, nesse comando, os pinos no chip I2C usados para conexões no LCD. Como esse pinos sempre são os mesmos, temos esse comando sendo usado para definir apenas o endereço, que para alguns módulos pode ser alterado. As demais configurações são padrões.
// Define os pinos do chip I2C usados para as conexões do LCD: // (Endereço,en,rw,rs,d4,d5,d6,d7,bl, blpol) LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
- Definindo as configurações iniciais
Dentro da função setup() utilizamos a função lcd.begin() (repare que o nome lcd corresponde ao objeto criado anteriormente) para inicializar o Display LCD I2C 20x4, de modo que, os parâmetros utilizados são o número de colunas e o número de linhas do display, nesta ordem.
void setup() { lcd.begin (20,4); }
Veja que, caso esteja usando um display LCD 16x2, aqui você definirá o tamanho do LCD com 16 colunas e 2 linhas:
void setup() { lcd.begin (16,2); //configuração para display 16x2 }
- Imprimindo informações no Display
O primeiro passo na manipulação do display consiste em localizar o cursor no local adequado. Este cursor nada mais é do que o elemento que apontará para o espaço que será preenchido com um caractere, sendo assim, utilizamos a função setCursor() para determinar qual será o ponto de partida da escrita de uma sequência de caracteres.
Perceba que a as posições dos espaços para escrita são dadas da seguinte forma:
Desta maneira, ao utilizarmos "0" e "0" como parâmetros, estaremos definindo a coordenada (0,0) como ponto de partida para o começo da escrita.
lcd.setCursor(0,0);
Em seguida, utilizamos a função print() para poder escrever algo a partir da posição que definimos como ponto de partida. Neste caso, simplesmente preencheremos com '*'.
lcd.print("********************");
Posteriormente, utilizamos novamente a função setCursor() para posicionar o cursor na segunda linha.
lcd.setCursor(9,1);
Com o cursor posicionado, escrevemos a palavra 'VIDA'.
lcd.print("VIDA");
Para continuar, posicionamos o cursor na próxima linha.
lcd.setCursor(4,2);
E escrevemos as palavras "DE SILICIO".
lcd.print("DE SILICIO");
Para finalizar, posicionamos o cursor no início da última linha.
lcd.setCursor(0,3);
Neste momento, iremos proceder da mesma maneira que fizemos na primeira linha, preenchendo a mesma com '*'.
lcd.print("********************");
Veja como ficou nossa função loop():
void loop() { lcd.setCursor(0,0); lcd.print("********************"); lcd.setCursor(0,1); lcd.print("aaaaaaaaaaaaaa"); lcd.setCursor(0,2); lcd.print("ssssssssssssssss"); lcd.setCursor(0,3); lcd.print("ddddddddddddddd"); }
Adaptando o programa para o display LCD 16x2
Para adaptar esse programa para o LCD 16x2 você precisa ter em mente que a tela é menor. Tendo 16 colunas e 2 linhas.
- Definindo as configurações iniciais
Dentro da função setup() utilizamos a função lcd.begin() para inicializar o Display LCD I2C 16x2, de modo que, os parâmetros utilizados são o número de colunas e o número de linhas do display, nesta ordem.
void setup() { lcd.begin (16,2); //configuração para display 16x2 }
- Imprimindo informações no Display
Na manipulação do display precisamos localizar o cursor no local adequado usando o comando setCursor() . Perceba que a as posições dos espaços para escrita são dadas da seguinte forma:
Em seguida basta usar o comando lcd.print().
Considerações finais
Neste tutorial buscamos elaborar um conteúdo semelhante ao que já temos sobre a utilização de displays LCD, no entanto, neste caso, utilizamos um display que ao invés de utilizar vários pinos numa placa Arduino, este necessita apenas de 4 pinos em virtude de a comunicação ser feita através do protocolo de comunicação I2C. Esperamos que você tenha gostado deste conteúdo, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.
Como fazer um tutorial?
Como fazer um tutorial?
Nós, da equipe Vida de Silício, apresentamos este documento como forma de demonstrar os principais pontos que devem ser observados pelos autores durante o processo de desenvolvimento de conteúdos para o portal.
Este material visa trazer algumas diretrizes de padronização para que todo conteúdo produzido obedeça certos requisitos de organização. Além disso, este também tem a função de nortear o autor no processo criação, por meio da execução de uma sequência predefinida passos.
É importante ter em mente de que, com esse padrão, conseguimos fazer um tutorial em uma linha de raciocínio didática. Ajuda a orientação tanto do autor durante a escrita como do leitor no momento do aprendizado.
Lembre-se que o objetivo do Portal Vida de silício é concentrar em um só lugar tutoriais de alta qualidade dos mais diversos assuntos. Tudo isso organizado de forma simples e intuitiva.
“Se quer ir rápido, vá sozinho. Se quer ir longe, vá acompanhado.”
Toda sugestão será bem vinda!
[toc]
Sobre qual assunto falar?
Você pode escrever sobre praticamente qualquer assunto ligado a robótica no portal Vida de Silício. Como queremos impactar o máximo de pessoas possíveis, a grande sacada é fazer conteúdos sobre assuntos que são de interesse geral.
- Tutoriais sobre o básico de Raspberry pi
- Tutorias Básicos de NodeMCU
- Tutoriais de sensores e módulos com Arduino
Existem muitas outras plataformas, tais como: Freescale , MSP, Beaglebone, Orange Pi. Se você tiver conhecimento sobre qualquer uma delas, sua contribuição com certeza será bem vinda. A única recomendação é que sempre se comece com um tutorial de apresentação da plataforma trabalhada. Um tutorial no estilo:"O que é Arduino?"
Criando um tutorial no Wordpress
Depois de criado sua conta como autor do site, você terá acesso exclusivo à área administrativa do Portal. Iremos explicar a partir daqui como criar seu primeiro tutorial
Criando um post
O primeiro passo para que um determinado conteúdo seja publicado no portal Vida de Silício consiste no acesso do autor ao ambiente de desenvolvimento adequado, utilizando o login e a senha previamente criados e cedidos pela nossa equipe.
Em seguida, deve-se localizar a opção Posts na barra de ferramentas localizada à esquerda da tela e posteriormente clicar em Adicionar novo.
Após a realização do procedimento anterior, o autor terá acesso à página em que poderá desenvolver o conteúdo desejado. Neste local, existem basicamente dois campos a serem preenchidos pelo mesmo: o título (lembre-se de escolher um que consiga expressar o conteúdo abordado de maneira clara) e o texto em si.
Em relação ao texto, torna-se necessário fazer uma ressalva, que consiste no fato de que o autor deve usar formatações diferentes para os tópicos e subtópicos existentes ao longo do conteúdo.
É importante resaltar que você precisa alternar a barra de ferramentas para que tenha acesso as configurações que usaremos para formatar o texto. Para isso clique no ícone "Alternar barra de ferramentas"
Como será visto posteriormente, o tutorial a ser desenvolvido possui basicamente três partes: Uma parte introdutória, uma parte de desenvolvimento e uma parte voltada para que o autor apresente um maior detalhamento sobre os elementos que constituem o projeto. Sendo assim, sempre que uma destas seções for iniciada, é necessário utilizar o Cabeçalho 1 para apresentar o título da mesma, no entanto, em relação às divisões internas de casa uma das partes citadas, utiliza-se o Cabeçalho 2 como título de cada subparte destas. Para as demais partes do texto, basta selecionar a opção Parágrafo.
Anexando imagens
Deve-se ressaltar que além dos elementos escritos, existe também a possibilidade de realizar a inclusão elementos gráficos no espaço reservado para o desenvolvimento. Para inserir, por exemplo, uma imagem no conteúdo que esta sendo produzido, basta que o autor clique no botão Adicionar mídia.
Em seguida, deve-se selecionar imagem desejada (este procedimento pode ser feito arrastando a imagem para a tela ou clicando no botão Selecionar arquivos e escolhendo a mesma manualmente).
Apenas como uma observação, sugerimos que o autor não utilize legenda nas imagens, no entanto, deve-se salientar que é necessário que o significado de uma eventual imagem utilizada esteja condizente com o conteúdo apresentado.
Inserindo códigos
Assim como é possível anexar imagens ao conteúdo, pode-se também realizar a escrita de códigos de programação caso seja necessário. Para realizar este procedimento, deve-se clicar no seguinte ícone.
Em seguida, basta somente escrever o código no espaço adequado (não é necessário que o autor altere qualquer uma das configurações preestabelecidas apresentadas nesta janela) e clicar em OK.
Será adiciona uma caixa com o código na área de edição do seu tutorial.
O código ficará assim quando postado:
//Exemplo de código // Função Setup void setup() { pinMode(LED_BUILTIN, OUTPUT); } // Função Loop void loop() { digitalWrite(LED_BUILTIN, HIGH); // Liga o LED delay(1000); // Espera 1 segundo digitalWrite(LED_BUILTIN, LOW); // Desliga o LED delay(1000); // Espera 1 segundo }
Inserindo partes expansíveis em seu tutorial
Caso queira, você pode criar partes expansíveis em seu tutorial tal como o exemplo abaixo.
Para usar isso em seu tutorial, você precisará usar da o seguinte código
Coloque aqui o conteúdo
Veja como ficou nesse tutorial:
Como o post deve está organizado?
Como forma de padronização, nós pedimos aos autores que dividam os conteúdos em algumas seções predeterminadas. Basicamente, um tutorial deve conter três partes, nas quais, a primeira delas deve ser voltada para introduzir o conteúdo para o leitor, a segunda corresponde ao desenvolvimento do projeto, enquanto a terceira faz explicação detalhada do funcionamento do mesmo.
- Parte 1: O que será aprendido; (H1)
- O que vamos aprender? (H2)
- Contexto histórico ou Aplicação prática (H2)
- Introdução e Explicação sobre os componentes-chave (H2)
- Parte 2: Mão à obra - Exemplo; (H1)
- Componentes necessários (H2)
- Montando o projeto (H2)
- Conectando ao computador (H2)
- Programando (H2)
- Colocando para funcionar (H2)
- Parte 3: Entendendo a fundo - Explicação detalhada do projeto da parte 2 (H1)
- Software (H2)
- Divida sua explicação em subtítulos; (H3)
- Hardware (Opcional) (H2)
- Divida sua explicação em subtítulos; (H3)
- Software (H2)
No fim do Tutorial costumamos adicionar uma quarta parte com os seguintes tópicos:
- Desafio (Opcional)
- Fechamento
Sobre o uso dos cabeçalhos
Para organizar esse esqueleto de forma visivelmente agradável, usamos a divisão em cabeçalhos. Dividimos o tutorial em três tipos de cabeçalhos
Cabeçalho 1 - Tópicos principais (H1)
Esse cabeçalho precisa ser azul e no formato Oswald.
Cabeçalho 2 - Divisão dos tópicos principais (H2)
Esse cabeçalho só precisa ser preto
- Cabeçalho 3 - Subtítulos (H3)
Esse cabeçalho é preto e adicionamos um traço antes do titulo.
Veja que no tópico anterior adicionamos na frente de cada título e subtítulo as abreviações: H1, H2 e H3. Eles mostram quais as configurações de cabeçalhos a serem usados para da um deles.
A seguir, disponibilizamos um roteiro para que fique mais fácil seguir as diretrizes necessárias para a realização de um tutorial bem claro e didático para o leitor.
O que vamos aprender? (Aqui entra o título que responde essa pergunta)
(QUAL É O OBJETIVO DESSE ARTIGO/POST/CONTEÚDO/MATERIAL? OU DEIXAR SEM NADA PARA O AUTOR COMEÇAR JÁ COM O TEXTO?)
Este espaço está reservado para que o autor fale sobre o objetivo do projeto proposto, ou seja, sugerimos para o autor que elabore um ou dois pequenos parágrafos explicando sobre o que será desenvolvido e o que o leitor poderá aprender com a leitura do conteúdo em questão.
Esse primeiro paragrafo é muito importante para que o Google consiga saber do que se trata o projeto e que ele possa direcionar às pesquisas certas. Então sempre coloque os assuntos principais em negrito, tal como o nome do módulo.
Contexto Histórico e aplicação prática
Nesta seção, sugere-se que o autor elabore um pequeno conteúdo referente ao contexto histórico do assunto proposto, de modo que, através da apresentação do mesmo, o leitor possa compreender um pouco a importância do que está sendo tratado, além de adquirir uma noção básica sobre a aplicabilidade do projeto e por que aprender sobre o mesmo é interessante.
Introdução aos Componentes-chave
Em geral, a maioria dos tutoriais possuem algum módulo ou controlador que pode ser encarado como o elemento mais importante do projeto, portanto, entende-se que, para uma melhor didática e clareza é necessário que o autor descreva um ou mais parágrafos sobre o(s) mesmo(s). O objetivo desta seção consiste em criar um ambiente em que o leitor, caso não tenha um entendimento muito abrangente sobre o assunto que está sendo tratado, possa sentir-se confortável, seguro e interessado para aprender sobre o mesmo.

Mãos à Obra - Desenvolvimento do projeto
Esta é a seção onde, de fato, ocorre o desenvolvimento do projeto em si. Sugerimos dividir esta seção em 5 partes para auxiliar na escrita do conteúdo proposto.
Componentes Necessários
Primeiramente, o autor deve listar os componentes que serão utilizados no desenvolvimento do projeto e também associá-los aos respectivos links existentes na loja. Veja o exemplo abaixo:
- 1 x Arduino Micro - Original
- 1 x Módulo ESP8266 WiFi ESP-01 A
- 1 x Protoboard 830 pontos
- 1 x Raspberry Pi 3 B
- 1 x Sensor de presença Pir - HC - SR501
Nesta seção, pedimos que o autor faça o uso marcadores para listar os componentes utilizados. Para realizar este procedimento deve-se apenas clicar no ícone correspondente conforme a figura abaixo.
Montando o Projeto
Em seguida, é necessário que o autor elabore uma imagem clara e didática do circuito utilizando o Fritzing (http://fritzing.org/home/).
Aqui é legal colocar uma foto do projeto montado depois do esquemático, caso seja possível, para que o leitor veja a montagem na prática.
Conectando o Arduino no Computador
Neste ponto, o autor deve lembrar ao leitor como configurar a IDE do Arduino para receber o código que será apresentado posteriormente. Este passo é necessário pois muitas vezes ocorrem erros ao carregar o programa no Arduino em virtude de uma configuração inadequada da interface utilizada. Sugerimos o uso do seguinte texto padrão:
Conecte seu Arduino ao computador e abra a IDE Arduino.
Antes de carregar um programa, você precisa selecionar qual porta você deseja usar para fazer carregar o programa no Arduino (upload). Dentro do Arduino IDE, clique no menu Ferramentas (tools) e abra o submenu Porta(Port). Clique na porta que seu Arduino está conectado, tal como COM3 ou COM4. Geralmente aparece o nome da placa Arduino : “COM3 (Arduino/Genuino Uno)”.
Você também precisa garantir que o tipo de placa apropriado está selecionado em Ferramentas(Tools) no submenu Placa (Board).
Programando
Esta seção é dedicada ao código da aplicação que está sendo desenvolvida neste tutorial.
- Biblioteca (Apenas se for usada alguma biblioteca)
Caso o autor tenha usado uma biblioteca é importante mostrar onde baixa-la e se possível como instala-la.
- Código do Projeto
Aqui basta que o autor coloque o código inteiro, comentado e de maneira bem organizada visualmente pois isso facilita para o leitor que não tem muita intimidade com a linguagem de programação utilizada.
É interessante escrever algo como:
"Segue o código a ser usado no exemplo"
// Programa Exemplo uint32_t referencia = 0; uint32_t tempoAtual; void setup() { pinMode(13,OUTPUT); // Configura o pino 13 (LED) como saída } void loop() { tempoAtual = millis(); // Captura o tempo atual // Verifica se já se passaram 1 segundo (1000 milissegundos) // desde a última vez em que o LED foi invertido if(tempoAtual - referencia >= 1000) { // Se sim, inverte o LED e atualiza a referencia digitalWrite(13,!digitalRead(13)); referencia = millis(); } }
Colocando para Funcionar
Aqui, sugerimos que o autor coloque uma foto do circuito montado fisicamente, um gif, ou até mesmo um pequeno vídeo, demonstrando a aplicação em funcionamento.
Entendendo a fundo
Esta é a terceira parte do tutorial que está sendo desenvolvido. Aqui, o autor deve elaborar duas seções para que possa explicar de maneira mais detalhada, tudo o que acontece por trás dos passos realizados anteriormente, ou seja, pede-se ao autor que elabore um conteúdo teórico que explique o funcionamento do hardware e também que realize a análise código que foi inserido no Arduino, porém, com um nível maior de detalhamento.
Aqui colocamos a explicação do software antes do Hardware, mas você pode explicar na ordem que preferir.
Software (Importante)
Aqui o autor precisa explicar os comandos usados ao longo do projeto de forma a explicar ao leitor a função de cada comando visando o melhor entendimento.
É importante dividir a explicação em subtítulos tais como o abaixo:
- Declarando biblioteca
Exemplo de explicação
#include <Wire.h> #include <LiquidCrystal_I2C.h>
- Função digitalRead()
Explicação exemplo.
estadoSensor = digitalRead(3);
Hardware (Opcional)
Aqui o autor pode explicar conceitos importantes sobre o Hardware tais como propriedades físicas ou como ele funciona.
Aqui vale também a divisão em subtítulos.
Desafio (OPCIONAL)
Caso o autor deseje, pode-se propor um desafio relacionado ao assunto tratado no conteúdo desenvolvido.
Fechamento
Para finalizar o tutorial, basta que o autor escreva um parágrafo de conclusão sobre o assunto e também peça ao leitor que não deixe de fazer seus elogios, críticas e sugestões sobre o conteúdo em questão. Além disso, também é importante abrir o espaço para que o leitor possa fazer perguntas e tirar as suas dúvidas.
Exemplos de tutoriais
Este foi o modelo referente à estrutura que deve ser seguida na elaboração de tutoriais. Acreditamos que, de acordo com esta proposta, seja possível produzir materiais de ótima qualidade e de fácil entendimento para o leitor.
Recomendamos que consulte alguns tutoriais para verificar essa organização:
- HC-SR501 - Utilizando o sensor de presença PIR com Arduino
- Display TFT 1.8″ ST7735 – Utilizando o display com o NodeMCU ou Arduino
- Sensor de Luz com LDR
- Medindo Temperatura com LM35
- Usando o buzzer com Arduino – Transdutor piezo elétrico
- Sensor Ultrassom HC-SR04
Como dito no inicio desse tutorial, esse padrão visa o melhor entendimento de quem ler mas também visa facilitar a vida de quem escreve criando uma linha de raciocínio fácil de ser seguida. Caso tenha uma sugestão de como melhorá-la, ficaremos contentes e te ouvir.
Finalizando o conteúdo
Após a finalização da elaboração do conteúdo, o autor deve enviar o mesmo para revisão e avisar a equipe Vida de Silício, por e-mail, que o material está concluído.
Respondendo aos comentários
Recomendamos que o autor fique atento aos comentários e sempre que possível responda as dúvidas dos leitores nos seus respectivos conteúdos. Assim você gerará uma interação bacana com seus leitores e ainda ajudará pessoas que provavelmente possuem a mesma dúvida.
Caso seja necessário, você pode utilizar links externos nas respostas, desde que não sejam de concorrentes diretos da loja Vida de Silício.