Kit Eletrónica [RISC-V]

Este é um guia para a placa de desenvolvimento ESP32-C6-DevKitM-1! Neste capítulo introdutório pelo mundo da eletrónica, exploraram-se as poderosas capacidades deste pequeno, mas versátil dispositivo. Quer sejas aprendiz no mundo dos microcontroladores ou já tenhas alguma experiência, este guia fornecer-te-á instruções passo a passo e exemplos práticos para te ajudar a tirar o máximo proveito do teu kit de eletrónica. Começaremos com conceitos básicos e progrediremos para projetos mais complexos. Vamos avançar e começar a criar!

Instalação

Esta página constiui um guia para a instalação do Arduino Integrated Development Environment (IDE), uma ferramenta de software utilizada no Departamento de Engenharia Eletrotécnica e de Computadores da Universidade de Coimbra. O Arduino IDE é essencial para estudantes e investigadores envolvidos em vários projetos de engenharia, particularmente aqueles relacionados com disciplinas de Engenharia Eletrotécnica e de Computadores. O guia abrange o processo passo a passo de download, instalação e configuração do software em diferentes plataformas, garantindo que os utilizadores tenham os recursos e as instruções necessários para configurar corretamente o Arduino IDE. Este recurso foi concebido para ajudar os utilizadores a superar possíveis desafios durante o processo de instalação, assegurando que possam utilizar o Arduino IDE de forma eficiente para os seus propósitos académicos e de investigação.

Contextualização:

O ESP32-C6-DevKitM-1 é uma placa de desenvolvimento que integra o microcontrolador ESP32-C6, parte da linha avançada de soluções IoT da Espressif. Este microcontrolador integra um CPU RISC-V de 32 bits, oferecendo conectividade sem fios com Wi-Fi 6 e Bluetooth 5 (LE). Projetado para criadores, o ESP32-C6-DevKitM-1 proporciona uma plataforma compacta e versátil para a criação e teste de aplicações IoT, com amplo suporte para operações seguras, de alto desempenho e baixo consumo de energia. A placa é especialmente indicada para prototipagem e implementação de dispositivos inteligentes.

esp32c6 000 esp32c6 00
Principais componentes do microcontrolador ESP32-C6-DevKitM-1 e elementos principais utilizados para a configuração e simulação de projetos de engenharia.

Procedimento:



esp32c6 01

Primeira etapa do processo de instalação do Arduino IDE: Acesso ao portal oficial para download do software.

Apresentam-se de seguida as etapas fundamentais para a configuração do Arduino IDE

https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json
esp32c6 002 esp32c6 003
espressif ESP32

e instalar a versão mais recente. Este processo de instalação pode demorar algum tempo.

esp32c6 004 esp32c6 005
esp32c6 006 esp32c6 007 esp32c6 008

Primeiro Programa:

Referências

[1] Espressif Systems, "ESP32-C6-DevKitM-1 User Guide," Espressif Systems, Aug. 2023. [Online]. Available: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitm-1/user_guide.html. [Accessed: 27-Aug-2024].

[2] Arduino, "Download and install Arduino IDE," Arduino, Sep. 2021. [Online]. Available: https://support.arduino.cc/hc/en-us/articles/360019833020-Download-and-install-Arduino-IDE. [Accessed: 27-Aug-2024].


Primeiro Programa

Boas-vindas ao guia introdutório para o seu primeiro programa Arduino! A programação com IDE Arduino é uma excelente maneira de mergulhar no mundo dos sistemas embebidos, permitindo controlar e interagir com o mundo físico através de código. Envolve a escrita de código no Ambiente de Desenvolvimento Integrado (IDE) do Arduino, onde um programa é chamado de sketch. Neste guia, vai aprender sobre as estruturas fundamentais de um sketch Arduino: as funções setup() e loop().

A função setup() é onde se inicializam as definições e configurações, sendo executada apenas uma vez quando a placa Arduino é ligada ou reiniciada. É aqui que se definem os modos dos pinos, se inicia a comunicação serial e se realizam outras tarefas de configuração necessárias para um dado projeto.

Por outro lado, a função loop() contém a lógica principal do programa e é executada continuamente, permitindo que a plca de desenvolvimento a programar realize tarefas repetitivas, como ler sensores, controlar saídas e responder a eventos.

Ao dominar estes conceitos, estará apto a criar projetos dinâmicos e interativos que respondem ao mundo ao seu redor. Vamos começar!

O código seguinte faz com que o Light-emitting diode (LED) da placa de desenvolvimento ESP32-C6-DevKitM-1 pisque, alternando entre ligado e desligado em intervalos regulares. Além disso, apresenta-se de seguida uma representação ilustrativo para referência.

/*
  BlinkRGB

  Demonstrates usage of onboard RGB LED on some ESP dev boards.

  Calling digitalWrite(RGB_BUILTIN, HIGH) will use hidden RGB driver.

  RGBLedWrite demonstrates control of each channel:
  void neopixelWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val)

  WARNING: After using digitalWrite to drive RGB LED it will be impossible to drive the same pin
    with normal HIGH/LOW level
*/
//#define RGB_BRIGHTNESS 64 // Change white brightness (max 255)

// the setup function runs once when you press reset or power the board
void setup() {
  // No need to initialize the RGB LED
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(RGB_BUILTIN, HIGH);  // Turn the RGB LED white
  delay(1000);
  digitalWrite(RGB_BUILTIN, LOW);  // Turn the RGB LED off
  delay(1000);
}
tft.gif
Montagem exemplificativa

Utilização do Monitor Serial no Arduino IDE

O Monitor Serial é uma ferramenta crucial dentro do Arduino IDE que permite enviar e receber dados entre a placa de desenvolvimento e o computador. Esta funcionalidade é extremamente útil para depuração, monitorização de leituras de sensores e interação com o programa do Arduino em tempo real.

Como Funciona o Monitor Serial

O Monitor Serial comunica com a placa de desenvolvimento através de uma conexão serial, que normalmente é estabelecida através do cabo USB que liga a placa ao computador. Esta conexão permite a transmissão de dados em texto entre o seu computador e a placa de desenvolvimento. Podem enviar-se comandos do Monitor Serial para a placa de desenvolvimento, e, por sua vez, a placa de desenvolvimento pode enviar de volta dados, que são exibidos na janela do Monitor Serial.

Para utilizar o Monitor Serial, siga estes passos:

1. Inicializar a Comunicação Serial: No sketch, deve inicializar-se a comunicação serial utilizando a função `Serial.begin()`. Esta função recebe um único argumento, a taxa de transmissão, que define a velocidade da comunicação em bits por segundo (bps). Uma taxa de transmissão comum é 9600.

void setup() {
	Serial.begin(9600); // Inicia a comunicação serial a uma taxa de 9600 bps
} 

2. Enviar Dados para o Monitor Serial: Pode enviar-se dados da placa de desenvolvimento para o Monitor Serial utilizando as funções `Serial.print()` ou `Serial.println()`. A função `Serial.print()` envia dados sem adicionar uma nova linha no final, enquanto que `Serial.println()` envia os dados seguidos de um caractere de nova linha.

void loop() {
	Serial.println("Olá, Mundo!"); // Envia "Olá, Mundo!" para o Monitor serial
	delay(1000); // Aguarda 1 segundo
}

3. Receber Dados do Monitor Serial: O Monitor Serial também pode enviar dados para a placa de desenvoldimento. Podem ler-se estes dados utilizando no sketch as funções `Serial.read()`, `Serial.available()`, e outras funções relacionadas. No exemplo seguinte ilustra-se a leitura de um caractereusando o Monitor Serial:

void loop() {
	if (Serial.available() > 0) { // Verifica se há dados disponíveis para leitura
    	char receivedChar = Serial.read(); // Lê o próximo caractere disponível
    	Serial.print("Recebido: ");
    	Serial.println(receivedChar); // Imprime o caractere recebido
	}
}

Segundo Programa

O sketch seguinte ilustra como monificar o sketch do primeiro programa anteriormente sugerido para começar a aproveitar as possibilidades do Monitor Serial:

/*
  BlinkRGB

  Demonstrates usage of onboard RGB LED on some ESP dev boards.

  Calling digitalWrite(RGB_BUILTIN, HIGH) will use hidden RGB driver.

  RGBLedWrite demonstrates control of each channel:
  void neopixelWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val)

  WARNING: After using digitalWrite to drive RGB LED it will be impossible to drive the same pin
    with normal HIGH/LOW level
*/
//#define RGB_BRIGHTNESS 64 // Change white brightness (max 255)

// the setup function runs once when you press reset or power the board
void setup() {
  // No need to initialize the RGB LED
  Serial.begin(9600);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(RGB_BUILTIN, HIGH);  // Turn the RGB LED white
  Serial.println("LED ligado"); // Imprime o caractere recebido
  delay(1000);
  digitalWrite(RGB_BUILTIN, LOW);  // Turn the RGB LED off
  Serial.println("LED desligado"); // Imprime o caractere recebido
  delay(1000);
}

Depois garantir a selecionação do dispositivo ESP32 adequado ( ESP32C6 Dev Module ), copiar o código anterior, compilar e carregar o código para a placa ESP32, deverá ser possível verificar o resultado.

tft.gif tft.gif

[Programa] LED com efeito dinâmico de mudança de cor

O seguinte código demonstra como controlar o LED RGB numa placa de desenvolvimento ESP32-C6. Especificamente, o código de exemplo mostra como criar um efeito dinâmico de mudança de cor, fazendo um ciclo através de diferentes cores no LED RGB da placa. Este exemplo serve como uma ilustração prática de como aproveitar as capacidades do ESP32-C6 para produzir padrões de luz visualmente atraentes. Ao executar este código, os utilizadores podem observar como o LED RGB transita suavemente por um espectro de cores, tornando-o uma referência útil para desenvolver efeitos semelhantes baseados em luz em outros projetos.

esp32c6 01 esp32c6 01
Adafruit NeoPixel
Usando a ferramenta de gestão de bibliotecas do IDE Arduino procurar e instalar a biblioteca: Adafruit_NeoPixel.
#include <Adafruit_NeoPixel.h>
#include <cmath>

// Pin and LED configuration
constexpr uint8_t LED_PIN = 8;
constexpr uint8_t NUM_LEDS = 1;

// NeoPixel object
Adafruit_NeoPixel rgbLed(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// Color structure
struct RGB {
    uint8_t r, g, b;
};

void setup() {
    rgbLed.begin();  // Initialize the RGB LED
    rgbLed.show();   // Turn off the LED (as it's initialized to all 0s)
}

void setColor(const RGB& color) {
    rgbLed.setPixelColor(0, rgbLed.Color(color.r, color.g, color.b));
    rgbLed.show();
}

// Convert HSV to RGB
RGB hsvToRgb(float h, float s, float v) {
    float c = v * s;
    float x = c * (1 - std::abs(std::fmod(h / 60.0, 2) - 1));
    float m = v - c;
    float r, g, b;

    if (h >= 0 && h < 60) {
        r = c, g = x, b = 0;
    } else if (h >= 60 && h < 120) {
        r = x, g = c, b = 0;
    } else if (h >= 120 && h < 180) {
        r = 0, g = c, b = x;
    } else if (h >= 180 && h < 240) {
        r = 0, g = x, b = c;
    } else if (h >= 240 && h < 300) {
        r = x, g = 0, b = c;
    } else {
        r = c, g = 0, b = x;
    }

    return {
        static_cast<uint8_t>((r + m) * 255),
        static_cast<uint8_t>((g + m) * 255),
        static_cast<uint8_t>((b + m) * 255)
    };
}

void loop() {
    constexpr unsigned long CYCLE_DURATION = 10000;  // 10 seconds for a full color cycle
    constexpr unsigned long STEPS = 1000;            // Number of steps in the cycle

    unsigned long startTime = millis();
    unsigned long currentTime;

    while (true) {
        currentTime = millis();
        float progress = static_cast<float>((currentTime - startTime) % CYCLE_DURATION) / CYCLE_DURATION;
        
        float hue = progress * 360.0f;  // Hue ranges from 0 to 360
        RGB color = hsvToRgb(hue, 1.0f, 1.0f);  // Full saturation and value
        
        setColor(color);
        
        delay(CYCLE_DURATION / STEPS);  // Small delay for smooth transition
    }
}
tft.gif tft.gif
Compilar e carregar o código para a placa ESP32-C6.
tft.gif
Montagem exemplificativa

Referências

[1] H4Fide, "ESP32-C6-RGB-LED-Control," GitHub, repository, 2024. [Online]. Available: https://github.com/h4fide/ESP32-C6-RGB-LED-Control. [Accessed: 27-Aug-2024].

[Programa] LED a piscar

Objetivo:

Utilizar o ESP32-C6-DevKitM-1 para alimentar um LED e obter um piscar controlado de forma programática.

Lista de material:

aaa.png

Contextualização:

Em eletrónica, um circuito LED é um circuito usado para alimentar um díodo emissor de luz (LED). O circuito deve fornecer corrente suficiente para acender o LED e evitar danos ao mesmo. O circuito mais simples para acionar um LED é através de uma resistência em série [3].

ESP32-C6-DevKitM-1

Apesar de se aconselhar a consulta da página do fabricante sobre o kit ESP32-C6-DevKitM-1 para mais detalhe, disponibilizam-se de seguida duas figuras com os componentes principais do kit bem como o esquema de terminais para referência.

esp32-devkitc-functional-overview.jpg
esp32-devkitC-v4-pinout.png
Breadboard

Uma breadboard ou placa de ensaio ou matriz de contactos é uma placa com furos e conexões condutoras tipicamente utilizada para a montagem de protótipos e projetos em estado inicial [1]. 
Deve ser tido em consideração que internamente a breadboard também é composta  por contactos metálicos, tipicamente organizados como se ilustra na figura em baixo. As linhas a azul e verde simbolizam ligações metálicas internas, ou seja, e por exemplo, tal como esquematizado, deve considerar-se que o orifício a1 está ligado internamente aos orifícios b1, c1, d1 e e1.

breadboard.png

Resistência

Uma resistência é um componente elétrico passivo de dois terminais que implementa resistência elétrica como um elemento de circuito [4]. Ainda que não seja do âmbito do presente documento detalhar este conceito, disponibiliza-se de seguida o esquema de quatro bandas e tabela de referência [2], tipicamente usados para indicar os valores associados, neste caso, as resistências.

resistor_b.png

Díodo emissor de luz (LED)

Um díodo emissor de luz (LED) é um dispositivo semicondutor que emite luz quando uma corrente flui através deste [3]. Destacar da figura seguinte a distinção entre ânodo e cátodo, tipicamente materializada por um comprimento diferente dos terminais de ligação (terminal do ânodo mais longo que o do cátodo), e um chanfro (ou superfície plana) no lado do cátodo.

led_cat_an.png

Procedimento:

As saídas digitais do ESP32-C6-DevKitM-1 podem ser programas para assumir determinados valores de tensão como 0V (GND) ou 3.3V (VCC). Fazendo uso desta possibilidade, e ligando o LED ao ESP32, deverá então ser possível obter um piscar do LED controlado de forma programática.

Escolhendo os terminais 5 e GND do ESP32 como referência deve considerar-se a seguinte montagem:

pisca1.png pisca2aa.png
Instruções:
/*
Pisca-pisca

Liga o LED por um segundo, desliga por um segundo e assim sucessivamente.
*/


// a função setup é executada pontualmente quando o botão reset é premido ou a placa é alimentada
void setup() {
  // inicializa o pino digital 5 como saída.
  pinMode(5, OUTPUT);
}

// a função loop é executada sucessivamente, uma e outra vez, e por aí em diante
void loop() {
  digitalWrite(5, HIGH);   // liga o LED 
  delay(1000);              // espera por um segundo
  digitalWrite(5, LOW);    // desliga o LED
  delay(1000);              // espera por um segundo
}
blink

Referências

[1] Wikipedia. Breadboard. url: https://en.wikipedia.org/wiki/Breadboard (acedido em 18/08/2023).

[2] Wikipedia. Electronic color code. url: https://en.wikipedia.org/wiki/Electronic_color_code (acedido em 18/08/2023).

[3] Wikipedia. LED circuit. url: https://en.wikipedia.org/wiki/LED_circuit (acedido em 18/08/2023).

[4] Wikipedia. Resistor. url: https://en.wikipedia.org/wiki/Resistor (acedido em 18/08/2023).

[Programa] Interruptor

Objetivo:

Utilizar o ESP32-C6-DevKitM-1 em conjugação com um interruptor e monitorizar estados.

Lista de material:

material_list.png

Contextualização:

Um interruptor é um componente elétrico que pode desconectar ou conectar o caminho condutor de um circuito elétrico, interrompendo a corrente elétrica ou conduzindo-a de um terminal para outro [1].

Interruptor

Um interruptor tipo botão tem tipicamente quatro terminais que estão conectados internamente aos pares. Por isso, numa utilização típica, apenas dois terminais, que não ligados internamente, são usados, como se ilustra na imagem seguinte:

switch_a.png switch_b.png switch_c.png switch_d.png

Ao ser pressionado o interruptor alterna entre os estados conetado e não conetado:

switch_e.png switch_e.png
(pressionado) (não pressionado)
switch_f.png switch_g.png
(fechado) (aberto)

Procedimento:

Escolhendo o terminal 23 e o GND do ESP32 como referência deve considerar-se o seguinte circuito:

interruptor_esq.png

Instruções:
/*
interruptor	tipo botão
*/	

#define BUTTON_PIN 23  // definição de terminal GPIO23 ligado ao interruptor

// Variáveis
int lastState = LOW;  // o estado anterior do terminal de entrada
int currentState;     // o estado atual do terminal de entrada

void setup() {
  // inicializa a comunicação serial a 115200 bits por segundo:
  Serial.begin(115200);
  // inicializa o terminal do interruptor tipo botão:
  // (o terminal de entrada toma o valor de HIGH quando o interruptor estiver aberto, 
  // e LOW quando estiver fechado)
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  // leitura do estado do interruptor tipo botão:
  currentState = digitalRead(BUTTON_PIN);

  if (lastState == HIGH && currentState == LOW) {
    Serial.println("o interruptor foi pressionado");
    digitalWrite(RGB_BUILTIN, HIGH);
  }
  else if (lastState == LOW && currentState == HIGH) {
    Serial.println("o interruptor foi solto");
    digitalWrite(RGB_BUILTIN, LOW);
  }

  // guarda o último estado
  lastState = currentState;
}
switch_f.png

Referências

[1] Wikipedia. Switch. url: https://en.wikipedia.org/wiki/Switch (acedido em 22/08/2023).

[Programa] Potenciómetro

Objectivo:

Utilizar o ESP32-C6-DevKitM-1 para ler valor de tensão de saída de um potenciómetro.

Lista de material:

Contextualização:

Um potenciómetro é um componente eletrónico que incorpora uma resistência elétrica ajustável [1].

Potenciómetro

Um potenciómetro possui tipicamente três terminais incluindo um contacto ajustável, deslizante ou rotativo, que forma um divisor de tensão ajustável [1].

eg_out_2.png eg_0_2.png eg_120_2.png eg_240_2.png
ESP32-C6-DevKitM-1

Apesar de se aconselhar a consulta da página do fabricante sobre o kit ESP32-C6-DevKitM-1 é possível considerar que em determinadas situações os terminais de entrada do microcontrolador ESP32 podem converter tensão (algo como uma quantidade analógica entre 0V e 3.3V) em um valor digital inteiro entre 0 e 4095 (num total de 212=4096 representações possíveis).

esp32.png

Procedimento:

Atentando ao objetivo enunciado, e escolhendo os terminais 2 (para o terminal de saída do potenciómetro), 3.3V e o GND do ESP32 como referência deve considerar-se a seguinte montagem:

interruptor_montagem_2.png

Instruções:
#include <Adafruit_NeoPixel.h>
#include <cmath>


// Pin and LED configuration
constexpr uint8_t LED_PIN = 8;
constexpr uint8_t NUM_LEDS = 1;

// NeoPixel object
Adafruit_NeoPixel rgbLed(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// Color structure
struct RGB {
    uint8_t r, g, b;
};

void setup() {
    rgbLed.begin();  // Initialize the RGB LED
    rgbLed.show();   // Turn off the LED (as it's initialized to all 0s)
    Serial.begin(115200);
}

void setColor(const RGB& color) {
    rgbLed.setPixelColor(0, rgbLed.Color(color.r, color.g, color.b));
    rgbLed.show();
}

// Convert HSV to RGB
RGB hsvToRgb(float h, float s, float v) {
    float c = v * s;
    float x = c * (1 - std::abs(std::fmod(h / 60.0, 2) - 1));
    float m = v - c;
    float r, g, b;

    if (h >= 0 && h < 60) {
        r = c, g = x, b = 0;
    } else if (h >= 60 && h < 120) {
        r = x, g = c, b = 0;
    } else if (h >= 120 && h < 180) {
        r = 0, g = c, b = x;
    } else if (h >= 180 && h < 240) {
        r = 0, g = x, b = c;
    } else if (h >= 240 && h < 300) {
        r = x, g = 0, b = c;
    } else {
        r = c, g = 0, b = x;
    }

    return {
        static_cast<uint8_t>((r + m) * 255),
        static_cast<uint8_t>((g + m) * 255),
        static_cast<uint8_t>((b + m) * 255)
    };
}

float floatMap(float x, float in_min, float in_max, float out_min, float out_max) {
	return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void loop() {
    constexpr unsigned long CYCLE_DURATION = 10000;  // 10 seconds for a full color cycle
    constexpr unsigned long STEPS = 1000;            // Number of steps in the cycle

    unsigned long startTime = millis();
    unsigned long currentTime;

    while (true) {
        // leitura do valor de entrada no terminal analógico GPIO33:
	      int analogValue = analogRead(2);
        Serial.println(analogValue);
	      // Normalização dos valores lidos para a tensão do potenciómetro
	      float voltage = floatMap(analogValue, 0, 4095, 0, 1.0);
        Serial.println(voltage);

        currentTime = millis();
        //float progress = static_cast<float>((currentTime - startTime) % CYCLE_DURATION) / CYCLE_DURATION;
        
        //float hue = progress * 360.0f;  // Hue ranges from 0 to 360
        float hue = voltage * 360.0f;  // Hue ranges from 0 to 360
        RGB color = hsvToRgb(hue, 1.0f, 1.0f);  // Full saturation and value
        //RGB color = hsvToRgb(255.0f, voltage, 1.0f);
        
        setColor(color);
        
        delay(CYCLE_DURATION / STEPS);  // Small delay for smooth transition
    }
}
out_hand_2.png

Referências:

[1] Wikipedia. Potentiometer. url: https://en.wikipedia.org/wiki/Potentiometer (acedido em 23/08/2023).

[Programa] SHT40 (exemplo I²C)

Objetivo:

Utilizar o ESP32-C6-DevKitM-1 para ler valores de temperatura de um sensor SHT40.

Lista de material:

8_material_list.png

Contextualização:

Grove - Temperature & Humidity Sensor (SHT40)

O sensor de temperatura e humidade da Seeed SHT40 é um sensor digital com interface I²C padrão [2].

Inter-Integrated Circuit (I²C) [3] 

O Inter-Integrated Circuit (I²C)[3] é um barramento serial que permite a co-existência de múltiplos controladores e periféricos (historicamente designados por master/slave) e considera essencialmente duas ligações:

SDA Serial Data Line
SDL Serial Clock Line

Ambas são bidirecionais e recorrem a resistências pull-up. As tensões típicas utilizadas são de +5 V ou +3,3 V, embora sejam permitidos sistemas com outras tensões.

O design de referência I²C possui um espaço de endereço de 7 bits, com uma extensão de 10 bits raramente utilizada. As velocidades de barramento I²C comuns são o modo padrão de 100 kbit/s existindo outras possibilidades para casos específicos.

A comunicação I²C segue uma estrutura organizada em pacotes de dados. Cada transação no barramento I²C inicia com uma condição de Start, seguida pelo envio de um byte de endereço, que identifica o dispositivo preriférico com o qual o controlador deseja comunicar. Após o endereço, o controlador pode enviar ou receber dados, dependendo da natureza da transação (escrita ou leitura).

Os principais elementos dos protocolos de mensagem do I²C incluem:

  1. Condição de Início ( Start ): O controlador gera uma transição do sinal SDA de alto para baixo enquanto SCL está alto, indicando o início de uma comunicação.

  2. Byte de Endereço: Após a condição de Start, o controlador envia um byte de endereço que contém o endereço do periférico alvo e um bit de leitura/escrita. O periférico com o endereço correspondente responde com um bit de reconhecimento ( ACK ).

  3. Dados: Os dados são transmitidos em bytes, seguidos por um bit de reconhecimento ( ACK ) enviado pelo receptor após cada byte. Se o receptor não reconhecer o byte, ele envia um bit de não reconhecimento ( NACK ).

  4. Condição de Paragem ( Stop ): A comunicação termina com uma condição de Stop, onde o controlador gera uma transição do sinal SDA de baixo para alto enquanto SCL está alto. Isso sinaliza o fim da transação no barramento I²C.

Essa estrutura simples e eficiente permite que o I²C suporte a comunicação entre múltiplos dispositivos de forma organizada, minimizando a necessidade de fios e facilitando a integração em sistemas eletrónicos complexos.

Desenvolvido pela Philips Semiconductor em 1982, o I²C é ideal para aplicações que exigem comunicação eficiente e de curto alcance entre componentes eletrónicos. Este protocolo suporta a comunicação entre múltiplos dispositivos, onde o dispositivo contolador comanda o barramento I²C e os peféricos respondem aos comandos recebidos. A simplicidade do I²C, combinada com a sua flexibilidade, torna-o uma escolha popular para interligar sensores, displays, memória e outros periféricos a microcontroladores em diversos projetos.

De seguida apresenta-se uma aplicação prática do I²C usando a placa de desenvolvimento ESP32-C6-DevKitM-1, que possui suporte integrado para I²C, em conjunto com o sensor de temperatura e humidade SHT40.

Procedimento:

Atentando nos terminais 3, 4, GND e 5V do ESP32 como referência deve considerar-se o seguinte ilustração de montagem:

8_i2c_setup.png

Instruções:
#include <Wire.h>
#include <Adafruit_SHT4x.h>

// Definição de uma nova instância da classe TwoWire
TwoWire myWire = TwoWire(0x44); // Usa o barramento I2C no ID 0 (podes alterar conforme necessário)
Adafruit_SHT4x sht40 = Adafruit_SHT4x();

void setup() {
  digitalWrite(RGB_BUILTIN, LOW);  // Turn the RGB LED off
  Serial.begin(115200);

  // Inicia a instância myWire no barramento I2C utilizando pinos SDA e SCL personalizados
  myWire.begin(4, 3); // Pinos SDA=4 e SCL=3 (substitua pelos pinos que preferires)

  // Inicializa o sensor SHT40 usando a instância personalizada de TwoWire
  if (!sht40.begin(&myWire)) {
    Serial.println("Falha ao inicializar o SHT40. Verifique a conexão I2C.");
    while (1) {
      delay(10);
    }
  }
  sht40.setPrecision(SHT4X_HIGH_PRECISION);
  sht40.setHeater(SHT4X_NO_HEATER);  
  Serial.println("Sensor SHT40 inicializado com sucesso!");
}

void loop() {
  digitalWrite(RGB_BUILTIN, LOW);  // Turn the RGB LED off

  sensors_event_t humidity, temp;
  sht40.getEvent(&humidity, &temp);

  Serial.print("Temperatura: ");
  Serial.print(temp.temperature);
  Serial.println(" °C");
  
  Serial.print("Humidade: ");
  Serial.print(humidity.relative_humidity);
  Serial.println(" %");

  delay(2000);  // Espera 2 segundos antes de nova leitura
  
  digitalWrite(RGB_BUILTIN, HIGH);  // Turn the RGB LED white
}
8_img_out_b.png

Referências:

[1] Adafruit. Adafruit Sensirion SHT40, SHT41 & SHT45 Temperature & Humidity Sensors. url: https://learn.adafruit.com/adafruit-sht40-temperature-humidity-sensor (acedido em 29/08/2023).
[2] Seeed Studio. Grove - Temperature & Humidity Sensor. url: https://wiki.seeedstudio.com/Grove-SHT4x/ (acedido em 29/08/2023).
[3] Wikipedia. I2C. url: https://en.wikipedia.org/wiki/I%C2%B2C (acedido em 29/08/2023).

[Programa] Lâmpada Zigbee

(provisório) [1]
8_material_list.png

Lista de Material

8_material_list.png

Notas (part I/II)

Este exemplo mostra como configurar o dispositivo final Zigbee e utilizá-lo como lâmpada de domótica de ligar/desligar.

Requisitos

Uma placa de desenvolvimento (ESP32-C6) como dispositivo final Zigbee (carregada com o exemplo Lâmpada Zigbee)

Arduino IDE
Lâmpada Zigbee

Notas (part II/II)

Este exemplo mostra como configurar o coordenador Zigbee e utilizá-lo como interruptor de luz de ligar/desligar para domótica.
Requisitos
Configurar o projeto

Confirmar a definição do GPIO do interruptor Switch  consultando a definição de `GPIO_INPUT_IO_TOGGLE_SWITCH`.

Arduino IDE
Interruptor Zigbee
Exemplo
8_material_list.png
Referência

[1] Espressif. arduino-esp32 Zigbee examples. url: https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/Zigbee (acedido em 30/08/2024).