Olá, como estão? Hoje iremos falar de uma tecnologia um pouco intrigante, quem nunca se perguntou como um passe de ônibus funciona, ou um cartão com aproximação? Eles usam uma tecnologia de aproximação chamada NFC, nós iremos abordar esse assunto mais a fundo, também iremos desenvolver um projeto simples NFC com ESP32 para que consigamos entender como essa tecnologia funciona.
Componentes Utilizados no Projeto NFC com ESP32
Funcionamento do Projeto NFC com ESP32
Iremos montar um projeto simples para que consigamos ver o funcionamento do modulo NFC, o projeto consiste em um ESP32 se comunicando com o PN532 a traves da Serial, e quando aproximarmos um NFC perto do leitor ele irá verificar se aquele leitor já foi cadastrado, caso já esteja cadastrado ele irá ligar o LED da esquerda, caso contrário ele irá ligar o LED da direita em seguida ele irá esperar 1 segundo para realizar o cadastro do NFC. Para realizar esse projeto será necessário entendermos o que é NFC e como utilizar a biblioteca PN532.
O que é NFC?
O NFC significa Near Field Communication (Comunicação de Campo Próximo), ele é uma tecnologia de comunicação entre dispositivos e maquinas de curta distancia de forma simples e segura, essa tecnologia foi inventada pela Sony e Nokia em 2004, que utiliza microchips e que contém informações e podem ser lidos por indução magnética através de bobinas como se fossem “antenas”, assim permitindo o recebimento de energia sem a necessidade da utilização de cabos de alimentação, nesse tipo de sistema utiliza-se um dispositivo passivo (o qual irá receber corrente elétrica e transmitir informações) e o ativo (o qual irá enviar corrente elétrica e receber informações).
O NFC significa Near Field Communication (Comunicação de Campo Próximo), ele é uma tecnologia de cEssa tecnologia está presente e muitas coisas como Celulares, anéis, relógios, cartões de bancos, ingressos, bilhetes de ônibus entre muitos outros…
O que são as Tags NFC?
As tags e cartões mais usados utilizam o padrão MIFARE CLASSIC e o padrão ISSO 14443 ou 14443A, nós iremos utilizar o cartão com o modelo de 13.56 Mhz com uma transferência de 106 Kbps, o espaço de armazenamento desse cartão é de 1 Kb, aparentemente é pouco, porém é mais que o suficiente para a maioria das aplicações sabendo que esses cartões foram feitos para transmitir pequenas quantidade de informação, como por exemplo um código de 4 dígitos para abrir o portão ou quando receber esses quatro dígitos realizar uma rotina pré-definida.
Estrutura de Armazenamento de Cartões NFC
O MIFARE CLASSIC possui uma forma própria de armazenamento de dados, ele possui divisões que são chamados blocos e setores, cada bloco é composto por 16 bytes, ou seja, o bloco 01 vai do 0 ao 15, do mesmo modo o bloco 02 vai do 16 ao 25 e assim por diante… Caso prefira em hexadecimal os blocos vão do 0 ao F. Já um setor é um conjunto de 4 blocos, ou seja, cada setor possui 64 bytes, sendo que o setor 0 é reservado, contendo a ID e informações do chip, já o último bloco de cada setor é reservado para as chaves dos setores. Cada setor possui duas chaves sendo elas A e B, a chave A é responsável por permitir somente a leitura. Entretanto a chave B só permitir a escrita, cada chave ocupa 6 bytes, para finalizar no mesmo setor temos 4 bytes que são utilizados para definir as permissões de cada chave. Os dados são escritos em hexadecimal. Um microchip de 1 Kb possui um total de 64 blocos e 16 setores.
NFC Module v3 (PN532) – Biblioteca PN532
Essa biblioteca é responsável pela comunicação com o modulo NFC PN532, esse modulo possui três interfaces de comunicação sendo elas:
- HSU – Comunicação High Speed Uart
- I2C – Comunicação Inter-Integrated Circuit
- SPI – Comunicação Serial Peripheral Interface
HSU – Comunicação High Speed Uart
Para utilizar a interface HSU iremos utilizar os pinos RX e TX do modulo PN532 ligando no TX e RX do ESP32 assim realizando a comunicação. Para utilizarmos essa interface no código, irá ficar da seguinte forma.
//Biblioteca -----------------------------------------------------------------------------------------
#include <PN532.h> // Responsável pelo funcionamento do Modulo
#include <PN532_HSU.h> // Responsável pela comunicação com o Modulo
//Declaração de Objetos ------------------------------------------------------------------------------
PN532_HSU pn532hsu(Serial); // Declara objeto de comunicação utilizando Serial
PN532 nfc(pn532hsu); // Declara objeto utilizando o objeto para comunicação
I2C – Comunicação Inter-Integrated Circuit
Para utilizar a interface I2C iremos utilizar os pinos SDA e SCL do modulo PN532 ligando no SDA e SCL do ESP32 assim realizando a comunicação. Para utilizarmos essa interface no código, irá ficar da seguinte forma.
//Biblioteca -----------------------------------------------------------------------------------------
#include <Wire.h> // Responsável por simplificar a comunicação i2c
#include <PN532.h> // Responsável pelo funcionamento do Modulo
#include <PN532_HSU.h> // Responsável pela comunicação com o Modulo
SPI – Comunicação Serial Peripheral Interface
Para utilizar a interface SPI iremos utilizar os pinos SCK, MISO, MOSI e SS do modulo PN532 ligando no SCK, MISO, MOSI e SS do ESP32 assim realizando a comunicação. Para utilizarmos essa interface no código, irá ficar da seguinte forma.
//Biblioteca -----------------------------------------------------------------------------------------
#include <SPI.h> // Responsável por simplificar a comunicação SPI
#include <PN532.h> // Responsável pelo funcionamento do Modulo
#include <PN532_HSU.h> // Responsável pela comunicação com o Modulo
//Declaração de Objetos ------------------------------------------------------------------------------
PN532_SPI pn532spi(SPI, 10); // Declara objeto de comunicação utilizando a SPI
PN532 nfc(pn532spi); // Declara objeto utilizando o objeto para comunicação
Funções da Biblioteca PN532
Essa biblioteca possui algumas funções sendo as principais:
- begin
- getFirmwareVersion
- SAMConfig
- readPassiveTargetID
- mifareclassic_AuthenticateBlock
- mifareclassic_ReadDataBlock
- mifareclassic_FormatNDEF
- mifareclassic_WriteDataBlock
- mifareclassic_WriteNDEFURI
Caso queira conferir todas as funções da biblioteca clique aqui.
Funções begin
A função begin inicializa o objeto que passaremos para ele.
Sintaxe:
nfc.begin();
Onde:
- nfc – Nome do objeto que declaramos.
- Retorna – True em caso de sucesso ou false em caso de falha.
Função getFirmwareVersion
Essa função é responsável por pegar informações referente ao modulo, sendo elas versão do chip e firmware.
Sintaxe:
nfc.getFirmwareVersion();
Onde:
- nfc – Nome do objeto que declaramos.
- Retorna – Um unit32_t com as informações em hexadecimal.
Função SAMConfig
Configura o modulo NFC para ler tag.
Sintaxe:
nfc.SAMConfig();
Onde:
- nfc – Nome do objeto que declaramos.
- Retorna – True em caso de sucesso ou false em caso de falha.
Função readPassiveTargetID
É responsável pela leitura do NFC obtendo assim o número da UID.
Sintaxe:
nfc.readPassiveTargetID (PN532_MIFARE_ISO14443A, uint8_t uid, uint8_t &uidLength);
Onde:
- nfc – Nome do objeto que declaramos.
- PN532_MIFARE_ISO14443A – Tipo do cartão utilizado.
- uid – Armazena ID da tag em um vetor uint8_t em hexadecimal.
- &uidLength – Armazena o tamanho da ID da tag em decimal.
- Retorna – True em caso de sucesso ou false em caso de falha.
Função mifareclassic_AuthenticateBlock
Esta função autentifica se a chave do bloco está correta.
Sintaxe:
nfc.mifareclassic_AuthenticateBlock (uint8_t uid, uint8_t uidLength, uint32_t block_num, uint8_t keyNumber, uint8_t keyData);
Onde:
- nfc – Nome do objeto que declaramos.
- uid – Informa a ID tag.
- uidLength – Informa o tamanho da tag.
- block_num – Informa o número do bloco.
- keyNumber – Informa o qual é a chave 0 para chave A e 1 para chave B.
- keyData – Informa a chave que está numa variável.
- Retorna – Um unit32_t com as informações em hexadecimal.
Função mifareclassic_ReadDataBlock
Lê um bloco da tag NFC.
Sintaxe:
nfc.mifareclassic_ReadDataBlock(uint8_t blockNumber, uint8_t *data);
Onde:
- nfc – Nome do objeto que declaramos.
- blockNumber – Informa o bloco que irá se lido.
- data – Variável que serão armazenados os dados em hexadecimal.
- Retorna – True em caso de sucesso ou false em caso de falha.
Função mifareclassic_FormatNDEF
Essa função é responsável por formatar a tag NFC apagando todos os dados.
Sintaxe:
nfc.mifareclassic_FormatNDEF();
Onde:
- nfc – Nome do objeto que declaramos.
- Retorna – Um unit32_t com as informações em hexadecimal.
Função WriteDataBlock
Escreve algo no bloco, porém a informação só pode ter 16 bytes no máximo e esse bloco tem que estar vazio. A informação é enviada em hexadecimal.
Sintaxe:
nfc.WriteDataBlock(uint8_t blockNumber, uint8_t *data);
Onde:
- nfc – Nome do objeto que declaramos.
- blockNumber – Informa o bloco que irá ser escrito.
- data – Variável que irá ser escrita na tag NFC em hexadecimal.
- block_num – Informa o número do bloco.
- Retorna – Um unit32_t com as informações em hexadecimal.
Função mifareclassic_WriteNDEFURI
Lê um bloco da tag NFC.Igual a função acima essa função é utilizada para escrever dados na tag NFC, porém diferente de gravar em um bloco essa função grava em um setor. Os dados podem ser enviados em com o tipo char até 38 bytes.Lê um bloco da tag NFC.
Sintaxe:
nfc.mifareclassic_WriteNDEFURI(uint8_t sectorNumber, uint8_t uriIdentifier, const char *url);
Onde:
- nfc – Nome do objeto que declaramos.
- SectorNumber – Número do setor que irá ser gravado a informação.
- uriIdentifier – Identificador do tipo que será armazenado.
- url – Vetor char que será armazenado.
- Retorna – Um unit32_t com as informações em hexadecimal.
Montagem do Circuito do Projeto NFC com ESP32
Logo após compra dos componentes na WJ Componentes, vamos à montagem! Nessa montagem utilizaremos a interface de comunicação HSU, então iremos ter que verificar se as chaves do modulo PN532 estão chaveadas em 0, após isso iremos conectar o VCC, GND, TX e RX do PN532 no VIN, GND, RX2 e TX2 do ESP32, agora conectamos o GND do ESP32 na protoboard e ligamos os pinos GPIO13 e GPIO12 nos LEDs.
Contudo segue abaixo uma imagem que demonstrando a montagem do circuito.
Código-fonte do Projeto NFC com ESP32
Em seguida segue abaixo o código-fonte completo do projeto.
//Biblioteca -----------------------------------------------------------------------------------------
#include <PN532.h> // Responsável pelo funcionamento do Modulo
#include <PN532_HSU.h> // Responsável pela comunicação com o Modulo
//Declaração de Objetos ------------------------------------------------------------------------------
PN532_HSU pn532hsu(Serial2); // Declara objeto de comunicação utilizando Serial2
PN532 nfc(pn532hsu); // Declara objeto utilizando o objeto para comunicação
//Defines --------------------------------------------------------------------------------------------
#define led1 12 // Define pino led1
#define led2 13 // Define pino led2
//Variáveis Globais ----------------------------------------------------------------------------------
uint8_t data1[16] = { 0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//Setup ----------------------------------------------------------------------------------------------
void setup() {
Serial.begin(115200); // Inicia Serial
pinMode(led1, OUTPUT); // Configura led1 como output
pinMode(led2, OUTPUT); // Configura led2 como output
nfc.begin(); // Inicializa o modulo
uint32_t versiondata = nfc.getFirmwareVersion(); // Obtém informações sobre o modulo
if (! versiondata) { // Verifica se a placa foi encontrada
Serial.print("Placa PN53x não encontrada");
while (1); // Loop infinito
}
Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);
nfc.SAMConfig(); // Configura o modulo para leitura RFID
Serial.println("Esperando ISO14443A Card ...");
}
//Loop -----------------------------------------------------------------------------------------------
void loop() {
uint8_t success; // Controle de sucesso
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer UID
uint8_t uidLength; // Tamanho da UID (4 ou 7 bytes depende do cartão)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); // Informações do NFC
if (success) {
Serial.println("Found an ISO14443A card"); // Imprime na Serial
Serial.print(" UID Length: "); Serial.print(uidLength, DEC); Serial.println(" bytes");
Serial.print(" UID Value: "); // Imprime na Serial
nfc.PrintHex(uid, uidLength); // Imprime a UID
Serial.println("");
if (uidLength == 4) { // Verifica se o cartão é de 4 bytes
Serial.println("Cartão é de 4 bytes");
uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // Chave A
uint8_t keyb[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // Chave B
success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 1, keyb); // Verifica chaves
if (success) {
Serial.println("Secetor 1 (Blocks 4..7) Autentificado");
uint8_t data[16]; // Declaração de um vetor de 16 posições
success = nfc.mifareclassic_ReadDataBlock(4, data); // Realiza a leitura do bloco 4
if (success) {
Serial.println("Leitura realizada do Bloco 4:");
nfc.PrintHexChar(data, 16); // Imprime o que está escrito no bloco 4
Serial.println("");
if (data[0] == 83) { // Verifica se é o mesmo código que cadastramos
Serial.println("Já Cadastrado");
digitalWrite(led1, HIGH); // Liga o led1
}
else {
Serial.println("Não cadastrado");
digitalWrite(led2, HIGH); // Liga o led2
delay(1000); // Espera 1s
success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 0, 1, keyb);
if (!success) {
Serial.println("Não Verificado"); // Imprime na Serial
return;
}
success = nfc.mifareclassic_FormatNDEF(); // Formata o cartão NFC
if (!success) {
Serial.println("Não Formatado"); // Imprime na Serial
return;
}
success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 6, 1, keyb);
if (!success) {
Serial.println("Não Verificado"); // Imprime na Serial
return;
}
success = nfc.mifareclassic_WriteDataBlock(6, data1); // Escreve no cartão NFC
if (success) {
Serial.println("Cadastrando"); // Imprime na Serial
for (int i = 0; i < 10; i++) { // Loop para LED piscar
digitalWrite(led1, HIGH); // Liga led1
digitalWrite(led2, HIGH); // Liga led2
delay(100); // Espera 0,1s
digitalWrite(led1, LOW); // Desliga led1
digitalWrite(led2, LOW); // Desliga led2
delay(100); // Espera 0,1s
}
}
else {
Serial.println("Não foi possível cadastrar"); // Imprime na Serial
digitalWrite(led1, HIGH); // Liga o led1
digitalWrite(led2, HIGH); // Liga o led2
delay(5000); // Espera 5s
}
}
delay(1000); // Espera 1s
digitalWrite(led1, LOW); // Desliga o led1
digitalWrite(led2, LOW); // Desliga o led2
}
else {
Serial.println("Ooops ... Não foi possível realizar a leitura. A chave estar correta?");
}
}
else {
Serial.println("Ooops ... Falha na autenticação. A chave estar correta?");
}
}
}
delay(1000); // Espera 1s
}
Vamos dar uma olhada mais de perto no código:
Incluindo Bibliotecas
Primeiramente temos que incluir as bibliotecas que iremos utilizar em nosso projeto.
//Biblioteca -----------------------------------------------------------------------------------------
#include <PN532.h> // Responsável pelo funcionamento do Modulo
#include <PN532_HSU.h> // Responsável pela comunicação com o Modulo
Declaração de Objetos
Após isso inicializamos o objeto do tipo PN532_HSU e PN532.
//Declaração de Objetos ------------------------------------------------------------------------------
PN532_HSU pn532hsu(Serial2); // Declara objeto de comunicação utilizando Serial2
PN532 nfc(pn532hsu); // Declara objeto utilizando o objeto para comunicação
Definição de Pinos
Agora nós definimos os led1 e led2.
//Defines --------------------------------------------------------------------------------------------
#define led1 12 // Define pino led1
#define led2 13 // Define pino led2
Variáveis Globais
Declaramos uma variável global que irá ser responsável pela escrita no cartão NFC.
//Variaveis Globais ----------------------------------------------------------------------------------
uint8_t data1[16] = { 0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Funções Setup
Agora na função setup (), iniciamos o monitor serial, definimos os LEDs como output e iniciamos objeto declarado do tipo PN532. Obtemos informações referente o modulo e imprimimos, caso não seja possível imprimir entramos num loop infinito, após isso configuramos também o modulo para ler tags NFC.
//Setup ----------------------------------------------------------------------------------------------
void setup() {
Serial.begin(115200); // Inicia Serial
pinMode(led1, OUTPUT); // Configura led1 como output
pinMode(led2, OUTPUT); // Configura led2 como output
nfc.begin(); // Inicializa o modulo
uint32_t versiondata = nfc.getFirmwareVersion(); // Obtém informações sobre o modulo
if (! versiondata) { // Verifica se a placa foi encontrada
Serial.print("Placa PN53x não encontrada");
while (1); // Loop infinito
}
Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);
nfc.SAMConfig(); // Configura o modulo para leitura RFID
Serial.println("Esperando ISO14443A Card ...");
}
Funções Loop
Na função void loop (), declaramos 3 variáveis do tipo uint8_t. Armazenamos em uid a ID do cartão e uidLength o tamanho e imprimimos isso na tela caso seja possível ler. Verificamos se o cartão é de 4 bytes caso for declaramos mais duas variáveis do tipo uint8_t sendo elas keya e keyb, também verificamos se a keyb está correta no setor 0. Lemos o que está escrito no bloco 4 e armazenamos em data, caso o primeiro caractere de data for igual a 83, então já foi cadastrado essa tag.
//Loop -----------------------------------------------------------------------------------------------
void loop() {
uint8_t success; // Controle de sucesso
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer UID
uint8_t uidLength; // Tamanho da UID (4 ou 7 bytes depende do cartão)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); // Informações do NFC
if (success) {
Serial.println("Found an ISO14443A card"); // Imprime na Serial
Serial.print(" UID Length: "); Serial.print(uidLength, DEC); Serial.println(" bytes");
Serial.print(" UID Value: "); // Imprime na Serial
nfc.PrintHex(uid, uidLength); // Imprime a UID
Serial.println("");
if (uidLength == 4) { // Verifica se o cartão é de 4 bytes
Serial.println("Cartão é de 4 bytes");
uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // Chave A
uint8_t keyb[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // Chave B
success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 1, keyb); // Verifica chaves
if (success) {
Serial.println("Secetor 1 (Blocks 4..7) Autentificado");
uint8_t data[16]; // Declaração de um vetor de 16 posições
success = nfc.mifareclassic_ReadDataBlock(4, data); // Realiza a leitura do bloco 4
if (success) {
Serial.println("Leitura realizada do Bloco 4:");
nfc.PrintHexChar(data, 16); // Imprime o que está escrito no bloco 4
Serial.println("");
if (data[0] == 83) { // Verifica se é o mesmo codigo que cadastramos
Serial.println("Já Cadastrado");
digitalWrite(led1, HIGH); // Liga o led1
}
Continuação Funções Loop
Caso o contrário, ainda não está castrado ele espera 1s e se o cartão ainda estiver encostado ele irá gravar a informação no cartão, formatando-o e escrevendo nele. Agora colocamos todos os else e fechamos os ifs.
else {
Serial.println("Não cadastrado");
digitalWrite(led2, HIGH); // Liga o led2
delay(1000); // Espera 1s
success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 0, 1, keyb);
if (!success) {
Serial.println("Não Verificado"); // Imprime na Serial
return;
}
success = nfc.mifareclassic_FormatNDEF(); // Formata o cartão NFC
if (!success) {
Serial.println("Não Formatado"); // Imprime na Serial
return;
}
success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 6, 1, keyb);
if (!success) {
Serial.println("Não Verificado"); // Imprime na Serial
return;
}
success = nfc.mifareclassic_WriteDataBlock(6, data1); // Escreve no cartão NFC
if (success) {
Serial.println("Cadastrando"); // Imprime na Serial
for (int i = 0; i < 10; i++) { // Loop para LED piscar
digitalWrite(led1, HIGH); // Liga led1
digitalWrite(led2, HIGH); // Liga led2
delay(100); // Espera 0,1s
digitalWrite(led1, LOW); // Desliga led1
digitalWrite(led2, LOW); // Desliga led2
delay(100); // Espera 0,1s
}
}
else {
Serial.println("Não foi possível cadastrar"); // Imprime na Serial
digitalWrite(led1, HIGH); // Liga o led1
digitalWrite(led2, HIGH); // Liga o led2
delay(5000); // Espera 5s
}
}
delay(1000); // Espera 1s
digitalWrite(led1, LOW); // Desliga o led1
digitalWrite(led2, LOW); // Desliga o led2
}
else {
Serial.println("Ooops ... Não foi possível realizar a leitura. A chave estar correta?");
}
}
else {
Serial.println("Ooops ... Falha na autenticação. A chave estar correta?");
}
}
}
delay(1000); // Espera 1s
}
E assim encerramos o projeto.
Agradecemos sua Presença
Por fim, espero que tenham gostado e aprendido. Compartilhe com seus colegas e deixe um comentário de qual projeto deveria ser o próximo aqui no Blog da WJ Componentes!!
Enfim estarei deixando os arquivos do código-fonte e Fritzing, software e sites utilizados e deixarei também o GitHub da biblioteca utilizada.
Fique à vontade para tirar suas dúvidas nos comentários.
Software e Sites Utilizados no Projeto NFC com ESP32
GitHub das Bibliotecas Utilizadas no Projeto NFC com ESP32
Post Relacionados
Posts mais Recentes
- Programando Relé RF 4331 -Instruções de emparelhamento do modo de alternância Modo de… Leia mais: Programando Relé RF 433
- Acionando motor DC por meio do pino “Touch” do ESP-32Neste projeto, vamos explorar uma aplicação ainda mais dinâmica e… Leia mais: Acionando motor DC por meio do pino “Touch” do ESP-32
- Acendendo led RGB por meio do pino “Touch” do ESP-32No último post, exploramos o fascinante mundo dos pinos touch… Leia mais: Acendendo led RGB por meio do pino “Touch” do ESP-32
- Utilizando os Pinos touch do ESP32Nesse projeto Vamos aprender a usar os pinos touch´s do… Leia mais: Utilizando os Pinos touch do ESP32
- Como Programar e Localizar o Endereço de uma Tela OLED I2C com Arduinoeste guia, vou levá-lo através dos passos para programar uma… Leia mais: Como Programar e Localizar o Endereço de uma Tela OLED I2C com Arduino
Julio Cesar Bonow Manoel
Cursando Engenharia da Computação pelo Centro Universitário Facens e atua no desenvolvimento de projetos na WJ Componentes. Participante da equipe de robótica Omegabotz.
Deixe um comentário