blog-eletrogate-logo-desktop blog-eletrogate-logo-mobile
  • Categorias
    • Voltar
    • INICIANTES
    • INTERMEDIÁRIOS
    • AVANÇADOS
    • divide
    • Automação Residencial
    • Componentes Eletrônicos
    • Impressão 3D
    • IoT
    • Modelagem 3D
    • Módulos Wifi
    • Por trás da tecnologia
    • Projetos
    • Raspberry Pi
    • Robótica
    • Sensores
    • Shields
    • Sistemas Operacionais
    • Tipos de Arduino
    • Tutoriais
  • Apostilas
  • Quem Somos
  • Seja um redator
  • Trabalhe Conosco
    • Categorias
      • Voltar
      • INICIANTES
      • INTERMEDIÁRIOS
      • AVANÇADOS
      • divide
      • Automação Residencial
      • Componentes Eletrônicos
      • Impressão 3D
      • IoT
      • Modelagem 3D
      • Módulos Wifi
      • Por trás da tecnologia
      • Projetos
      • Raspberry Pi
      • Robótica
      • Sensores
      • Shields
      • Sistemas Operacionais
      • Tipos de Arduino
      • Tutoriais
    • Apostilas
    • Quem Somos
    • Seja um redator
    • Trabalhe Conosco
Loja Eletrogate
voltar
  • Introdução
  • Mutex
  • Criando Mutex
  • Obtendo o Mutex
  • Liberando o mutex
  • Deletando um mutex
  • Projeto de demonstração
  • Resultado da aplicação
  • Conclusão
  • Referência
  • Sobre o Autor
Sistemas Operacionais

FreeRTOS – Utilizando MUTEX

Eletrogate 22 de março de 2022Atualizado em: 06 abr 2022

Introdução

Olá, caro leitor. Tudo bem? Daremos sequência à série de artigos abordando o desenvolvimento de aplicação utilizando o sistema operacional de tempo real, FreeRTOS. No último artigo da série, tratamos a respeito de semáforo binário, vendo que esse recurso é utilizado como mecanismo de sincronismo de processos e exclusão mútua. Neste post, será apresentado o recurso de Mutex, oferecido pelo FreeRTOS.


Mutex

Mutex é acrônimo para “mutual exclusion”, o termo inglês para “exclusão mútua”. É uma técnica de programação utilizada em programa concorrente, para impedir que dois ou mais processos tenham acesso de maneira simultânea a um determinado recurso compartilhado. 

Mutex, no FreeRTOS basicamente são semáforos binário equipados com o mecanismo de herança de prioridade. Essa funcionalidade faz com que a tarefa que obtém o mutex tenha a sua prioridade elevada temporariamente se outra tarefa de maior prioridade tentar obter o mesmo mutex. A tarefa que está em posse do mutex, após terminar de utiliza-lo deve o liberar, permitindo, assim, que outras tarefas tenham a oportunidade de acessar tal recurso. Essas características tornam o mutex a melhor escolha para implementar técnica de exclusão mútua simples.

É importante salientar que mutexes no FreeRTOS não devem ser usados ​​a partir de uma interrupção porque:

  • Eles incluem um mecanismo de herança de prioridade que só faz sentido se o mutex for utilizado a partir de uma tarefa, não de uma interrupção.
  • Uma interrupção não pode ser bloqueada para aguardar que um recurso protegido por um mutex fique disponível.

Outra característica do FreeRTOS é que as funções de API de acesso ao mutex e semáforo são compartilhadas. Isso permite que um tempo de bloqueio seja especificado. O tempo de bloqueio indica o número máximo de “Ticks” que uma tarefa deve entrar no estado de bloqueio ao tentar “obter” um mutex se o mutex não estiver disponível.


Criando Mutex

Conforme citado nos artigos anteriores, o FreeRTOS contém duas abordagens para manipular a memória RAM; a primeira utilizando o método de alocação da memória RAM dinâmica, a partir do Heap, e a segunda por alocação de memória RAM estática em tempo de compilação. Para entender melhor a diferença entre alocação de memória estática vs dinâmica, consulte o link. Para esse e os demais artigos, vamos explicar as funções do FreeRTOS que trabalham com alocação de memória RAM dinâmica. 

Para criar uma mutex, é necessário declarar uma variável do tipo “SemaphoreHandle_t”. Sim, usa o mesmo tipo de variável utilizada para semáforo. Como dito anteriormente, semáforo e mutex compartilham as mesmas API’s. Essa variável será utilizada como o identificador do mutex.

Protótipo da função:

SemaphoreHandle_t xSemaphoreCreateMutex(void)

Retorno:

  • Quando o mutex é criado com sucesso, a função retorna o identificador. Na ocorrência de falha na criação, o valor retornado é qual a NULL.

Obtendo o Mutex

Conforme citado anteriormente, as funções de mutex e semáforo compartilham as mesmas API’s. Então, a função para obtenção do mutex é a mesma utilizada para obter o semáforo. Porém, diferente dos semáforos, mutexes não podem ser executados a partir de funções de interrupções, sendo usados apenas em tarefas. Para manipular o mutex, temos que utilizar as funções de uso genérico, não a função de uso especializado.   

xSemaphoreTake é a função genérica para obtenção do mutex.

Protótipo da função:

xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait );

Parâmetros: 

  • xSemaphore: O identificador do semáforo a ser obtido.
  • xTicksToWait: O tempo em Ticks para aguardar o mutex ficar disponível. A macro portTICK_PERIOD_MS pode ser utilizada para converter o valor em milissegundos. Também é possível bloquear a tarefa até que o mutex esteja livre utilizando a macro portMAX_DELAY, sem limite de tempo. Para que esse recurso esteja disponível, é necessário habilitar o recurso INCLUDE_vTaskSuspend. Para mais informações, consulte o link.

Retorno: 

  • A função retornará o valor pdTRUE quando o mutex for obtido com sucesso. Caso a função retorne o valor pdFALSE, significa que o tempo para aguardar a disponibilidade do mutex expirou.

Liberando o mutex

Uma vez obtido um determinado mutex, executado o algoritmo do recurso compartilhado, é necessário liberar o mesmo para que outras funções da aplicação possam utilizar. Para liberar o mutex, é recomendado o uso da função genérica.  

xSemaphoreGive é função genérica para liberar o mutex.  

Protótipo da função

xSemaphoreGive( SemaphoreHandle_t xSemaphore );

Parâmetro:

  • xSemaphore: O identificador do mutex a ser liberado. 

Retorno:

  • A função retorna o valor pdTRUE quando o mutex é liberado com sucesso. Quando o valor retornado é igual a pdFALSE, significa que ocorreu alguma falha. 


Deletando um mutex

Como qualquer objeto no FreeRTOS, o mutex pode ser deletado. Quando é excluído um mutex, é liberada toda a memória RAM alocada. 

Nota: É recomendado não excluir um mutex que tenha tarefas bloqueadas nele (tarefas que estão no estado bloqueado aguardando a disponibilidade do mutex).

Protótipo da função

void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );

Parâmetro: 

  • xSemaphore: O identificador do mutex que está sendo deletado. 


Projeto de demonstração

A aplicação desenvolvida tem como objetivo demonstrar o uso compartilhado do barramento I2C por diferentes tarefas. O projeto utiliza o Módulo Real Time Clock RTC DS1307 (RTC Tiny), dispositivo que contém o circuito integrado (CI) DS1307 e o CI AT24C32. O DS1307 é um RTC (Real Time Clock – relógio de tempo real), componente que, como próprio no sugere, é relógio e também um calendário. O segundo CI presente no módulo é memória do tipo EEPROM de 32 KBits. 

Além do módulo RTC Tiny, a aplicação conta com o push-button. O algoritmo desenvolvido consiste em um contador de pulsos que registra na memória EEPROM a data e hora da ocorrência de cada pulso. 

O projeto desenvolvido conta com três tarefas e uma rotina para o tratamento da interrupção dedicada aos eventos do push-button. A primeira é a “Tarefa LED”, é responsável pelo acionamento do LED “on-board”. A segunda, a “Tarefa Relógio” que, por sua vez, é encarregada pela a comunicação com o CI DS1307. Por último, temos a “Tarefa Contador de Pulso”, responsável por efetuar a contagem de pulso e salvar os dados na memória EEPROM.

Para exemplificar, o projeto possui dois mutexes. O primeiro é para gerenciar o acesso do barramento da comunicação I2C. O segundo mutex é dedicado a controlar o acesso de variável global utilizada na aplicação, uma struct que contém data e hora.

Circuito elétrico do projeto

Circuito elétrico do projeto

Material utilizado: 

  1. Módulo WiFi ESP32s Bluetooth 38 pinos
  2. Módulo Real Time Clock RTC DS1307 (RTC Tiny)
  3. Push Button (Chave Táctil) 
  4. Resistor 10K  
/**
 * @file main.cpp
 * @author Evandro Teixeira
 * @brief 
 * @version 0.1
 * @date 14-02-2022
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#include <Arduino.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
#include "RTCTiny.hpp" // https://github.com/evandro-teixeira/RTC_Tiny

#define COLOR_BLACK         "\e[0;30m"
#define COLOR_RED           "\e[0;31m"
#define COLOR_GREEN         "\e[0;32m"
#define COLOR_YELLOW        "\e[0;33m"
#define COLOR_BLUE          "\e[0;34m"
#define COLOR_PURPLE        "\e[0;35m"
#define COLOR_CYAN          "\e[0;36m"
#define COLOR_WRITE         "\e[0;37m"
#define COLOR_RESET         "\e[0m"
#define AT24C32_ADDRESS     0x50
#define DS1307_ADDRESS      0x68
#define BUTTON              15    // Pino do botão 
#define LED_BOARD           2     // Pino do LED
#define DEBOUNCE_BUTTON     1000  // Tempo do debounce do botão

/**
 * @brief 
 */
const char MesesDoAno[12][4] = {"Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"};
const char DiasDaSemana[7][14] = {"Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sabado"};

/**
 * @brief Cria objeto RTC Tiny
 * 
 * @return RtcTiny 
 */
RtcTiny ModuleRTC(AT24C32_ADDRESS, DS1307_ADDRESS);

/**
 * @brief 
 */
void Tarefa_LED(void *parameters);
void Tarefa_Relogio(void *parameters);
void Tarefa_ContadorPulso(void *parameters);
void SetVarRTC(DS1307Data_t Data);
DS1307Data_t GetVarRTC(void);

/**
 * @brief 
 */
SemaphoreHandle_t xSemaphore_Pulso = NULL;
SemaphoreHandle_t xMutex_I2C = NULL;
SemaphoreHandle_t xMutex_Var = NULL;
DS1307Data_t RTCData;

/**
 * @brief Função da interrupção botão
 */
void IRAM_ATTR Button_ISR()
{
  // tempo da ultima leitura do botão
  static uint32_t last_time = 0; 

  // Algoritmo de debounce do botão
  if( (millis() - last_time) >= DEBOUNCE_BUTTON)
  {
    last_time = millis();
    xSemaphoreGiveFromISR(xSemaphore_Pulso, (BaseType_t)(pdFALSE));
  }
}

/**
 * @brief 
 */
void setup() 
{
  // Inicializa a Serial 
  Serial.begin( 115200 );
  Serial.printf("\n\rFreeRTOS - Mutex\n\r");

  ModuleRTC.Init();

  // Inicializa pino 15 como entra e inicializa interrupção do botão
  pinMode(BUTTON, INPUT);
  attachInterrupt(BUTTON, Button_ISR, RISING);

  // Inicializa pino do LED on Board
  pinMode(LED_BOARD,OUTPUT);
  digitalWrite(LED_BOARD,LOW);

  // Cria semafaro binario xSemaphore_Pulso
  vSemaphoreCreateBinary( xSemaphore_Pulso );
  if(xSemaphore_Pulso == NULL)
  {
    Serial.printf("\n\rFalha em criar o semafaro para Contador Pulso");
  }
  // Obtem o semafaro xSemaphore_Pulso
  xSemaphoreTake(xSemaphore_Pulso,(TickType_t)100);

  // Cria Mutex para gestão do barramento I2C
  xMutex_I2C = xSemaphoreCreateMutex();
  if(xMutex_I2C == NULL)
  {
    Serial.printf("\n\rFalha em criar o Mutex para I2C");
  }

  xMutex_Var = xSemaphoreCreateMutex();
  if(xMutex_Var == NULL)
  {
    Serial.printf("\n\rFalha em criar o Mutex para variavel global");
  }

  // Cria tarefas da aplicação
  xTaskCreate(Tarefa_LED, "LED", configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY + 1, NULL);
  xTaskCreate(Tarefa_Relogio, "Relogio", configMINIMAL_STACK_SIZE * 3, NULL, tskIDLE_PRIORITY + 2, NULL);
  xTaskCreate(Tarefa_ContadorPulso, "Contador Pulso", configMINIMAL_STACK_SIZE * 3, NULL, tskIDLE_PRIORITY + 3, NULL);
}

/**
 * @brief 
 */
void loop() 
{
  Serial.printf("\n\rSupende tarefa LOOP");
  vTaskSuspend(NULL);
}

/**
 * @brief 
 * 
 * @param parameters 
 */
void Tarefa_LED(void *parameters)
{
  static int valueOld = 0xFF;
  int value = 0;
  
  while (1)
  {
    // le o valor do botão 
    value = digitalRead(BUTTON);

    // detecta borda de subida
    if((value != valueOld) && (value == HIGH))
    {
      digitalWrite(LED_BOARD,LOW);
      Serial.print(COLOR_BLUE);
      Serial.printf("\n\rLED OFF");
      Serial.print(COLOR_RESET);
    }
    else 
    {
      // detecta borda de descida
      if((value != valueOld) && (value == LOW))
      {
        digitalWrite(LED_BOARD,HIGH);
        Serial.print(COLOR_BLUE);
        Serial.printf("\n\rLED ON");
        Serial.print(COLOR_RESET);
      }
    }
    // Update
    valueOld = value;

    vTaskDelay(10/portTICK_PERIOD_MS);
  }
}

/**
 * @brief 
 * 
 * @param parameters 
 */
void Tarefa_Relogio(void *parameters)
{
  DS1307Data_t Data;

  while (1)
  {
    // Obtem o Mutex-I2C
    xSemaphoreTake(xMutex_I2C,portMAX_DELAY );
    // Le os dados do RTC via barramento I2C
    ModuleRTC.ReadRTC(&Data);
    // libera o Mutex-I2C
    xSemaphoreGive(xMutex_I2C);

    // salva dados na memoria global
    SetVarRTC(Data);

    // Imprimi no barramento serial Data e Hora
    Serial.printf("\n\r%02d:%02d:%02d - ",Data.Hours,
                                          Data.Minutes,
                                          Data.Seconds);
    Serial.printf("%s, %02d de %s de %d ",DiasDaSemana[ (Data.Day-1) ],
                                          Data.Date ,
                                          MesesDoAno[ (Data.Month-1) ], 
                                          (2000 + Data.Year) ); 
    vTaskDelay(1000/portTICK_PERIOD_MS);
  }
}

/**
 * @brief 
 * 
 * @param parameters 
 */
void Tarefa_ContadorPulso(void *parameters)
{
  const uint16_t endProximo = 0x0000;
  uint16_t contadorPulso = 0;
  uint16_t endMemoriaROM = 0;
  uint8_t buffer[2] = {0};
  DS1307Data_t dataRTC;

  // Obtem o Mutex-I2C
  xSemaphoreTake(xMutex_I2C,portMAX_DELAY );
  // Salva o endereço proximo dado
  ModuleRTC.WriteROM(endProximo, 0x00 );
  ModuleRTC.WriteROM(endProximo + 1, 0x00 );
  // libera o Mutex-I2C
  xSemaphoreGive(xMutex_I2C);

  while (1)
  {
    if(xSemaphoreTake(xSemaphore_Pulso,portMAX_DELAY) == pdTRUE)
    {
      // obtem data e hora 
      dataRTC = GetVarRTC();

      // incrementa o contador de pulso
      contadorPulso++;
      Serial.print(COLOR_YELLOW);
      Serial.printf("\n\rContador de Puslo: %d",contadorPulso);

      // Obtem o Mutex-I2C
      xSemaphoreTake(xMutex_I2C,portMAX_DELAY );

      // Le dados no barramento I2C
      // Obtem o endereço do proximo dado a ser salvo
      ModuleRTC.ReadROM(endProximo, &buffer[0] );
      ModuleRTC.ReadROM(endProximo + 1, &buffer[1] );
      endMemoriaROM  = (uint16_t)(buffer[0] << 8);
      endMemoriaROM += (uint16_t)(buffer[1] );
      Serial.printf("\n\r-->endMemoriaROM: %d",endMemoriaROM);
/*     ________ ________
      |   Add  |  Data  |
      |--------|--------|
      | 0x0000 |  XXXX  | Proximo endereço
      |--------|--------|
      | 0x---- |  XXXX  | Numero de pulso MSB
      | 0x---- |  XXXX  | Numero de pulso LSB
      | 0x---- |  XXXX  | Hora
      | 0x---- |  XXXX  | Min
      | 0x---- |  XXXX  | Sec
      | 0x---- |  XXXX  | Dia 
      | 0x---- |  XXXX  | Mes
      |________|________| Ano    */
      // Escreve no barramento I2C
      // Salva os dados na memoria 
      ModuleRTC.WriteROM(endMemoriaROM++, ((contadorPulso & 0xFF00) >> 8) );
      ModuleRTC.WriteROM(endMemoriaROM++, ((contadorPulso & 0x00FF) >> 0) );
      ModuleRTC.WriteROM(endMemoriaROM++, dataRTC.Hours );
      ModuleRTC.WriteROM(endMemoriaROM++, dataRTC.Minutes );
      ModuleRTC.WriteROM(endMemoriaROM++, dataRTC.Seconds );
      ModuleRTC.WriteROM(endMemoriaROM++, dataRTC.Date );
      ModuleRTC.WriteROM(endMemoriaROM++, dataRTC.Month );
      ModuleRTC.WriteROM(endMemoriaROM++, dataRTC.Year );

      // Salva o endereço proximo dado
      ModuleRTC.WriteROM(endProximo, ((endMemoriaROM & 0xFF00) >> 8) );
      ModuleRTC.WriteROM(endProximo + 1, ((endMemoriaROM & 0x00FF) >> 0) );

      Serial.printf("\n\r<--endMemoriaROM: %d",endMemoriaROM);
      Serial.print(COLOR_RESET);

      // libera o Mutex-I2C
      xSemaphoreGive(xMutex_I2C);

    }
  }
}

/**
 * @brief Set the Global Variable RTC object
 * 
 * @param Data 
 */
void SetVarRTC(DS1307Data_t Data)
{
  // Obtem o Mutex Variavel Global
  xSemaphoreTake(xMutex_Var,portMAX_DELAY );
  RTCData = Data;
  // libera o Mutex Variavel Global
  xSemaphoreGive(xMutex_Var);
}

/**
 * @brief Get the Global Variable RTC object
 * 
 * @return DS1307Data_t 
 */
DS1307Data_t GetVarRTC(void)
{
  DS1307Data_t Data;
  // Obtem o Mutex Variavel Global
  xSemaphoreTake(xMutex_Var,portMAX_DELAY );
  Data = RTCData;
  // libera o Mutex Variavel Global
  xSemaphoreGive(xMutex_Var);
  return Data;
}

 


Resultado da aplicação

A seguir, temos a imagem com as mensagem de cada tarefa impressas no terminal serial.

LOG das mensagens no barramento serial

LOG das mensagens no barramento serial

As mensagens na figura foram enumeradas para detalhar o comportamento do algoritmo implementado no projeto de demonstração:

  1. Após a inicialização da comunicação serial, é transmitida a mensagem “FreeRTOS – Mutex”.
  2. Observe que a mensagem “Suspende tarefa LOOP” é impressa uma única vez. Isso ocorre porque a função loop se comporta como uma tarefa agendada no escalonador do sistema operacional. Portanto, podemos utilizar os recursos oferecidos pelo FreeRTOS. Neste caso, foi utilizada a função que suspende a execução de tarefa (vTaskSuspend).
  3. A “Tarefa Relógio” é executada a cada segundo. O algoritmo implementado obtém o mutex destinado para barramento I2C e atualiza a data e hora acessando o módulo RTC Tiny. Em seguida, é liberado o mutex e salva a data e hora atualizadas na variável global da aplicação. Para acessar essa variável, é necessário obter o mutex “Var”.
  4. Com o botão pressionado, a função que trata a interrupção desbloqueia a “Tarefa Contador de Pulso”. O algoritmo da tarefa lê a data e hora por meio da variável global e libera o mutex em seguida. O contador de pulso é, então, incrementado. Em seguida, inicia-se o processo de salvar os dados na memória EEPROM. Para executar essa atividade, é obtido o mutex “I2C”, que inicia a comunicação no barramento I2C com o CI AT24C32 e, ao final, o libera.
  5. Ao pressionar novamente, o algoritmo da “Tarefa Contador de Pulso” é executado novamente. Observe que o valor da contagem de pulso foi incrementado e note, também, que os dados são salvos em novos endereços da memória EEPROM. 


Conclusão

Neste artigo da série sobre o FreeRTOS, foi apresentado o recurso de Mutex. Esse é um dos tipos de mutex oferecidos pelo sistema operacional. Mutex é um dos principais mecanismos empregados para controle de acesso a recursos compartilhados entre processos.  

Detalhamos as principais API’s para o manuseio de mutex disponível no FreeRTOS e foi apresentado uma aplicação de demonstração. O projeto desenvolvido traz dois exemplos de uso de mutex; um faz o controle de acesso a uma variável global da aplicação e o outro gerencia o acesso ao barramento I2C, utilizado para acessar os CI’s presentes no módulo RTC Tiny.

Ao final, analisamos o LOG de mensagem impressa no barramento serial para o melhor entendimento do algoritmo.

Para os próximos artigos, serão apresentados mais recursos do FreeRTOS. O que você achou? Você já utiliza o FreeRTOS em seus projetos? Deixe o seu comentário abaixo.


Referência

FreeRTOS Mutexes

https://www.freertos.org/Real-time-embedded-RTOS-mutexes.html 

FreeRTOS Semaphore / Mutexes 

https://www.freertos.org/a00113.html

Wikipedia – Programação concorrente

https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_concorrente 

Wikipedia – Processo (informática)

https://pt.wikipedia.org/wiki/Processo_(inform%C3%A1tica) 

Wikipedia – Exclusão mútua

https://pt.wikipedia.org/wiki/Exclus%C3%A3o_m%C3%BAtua#:~:text=Exclus%C3%A3o%20m%C3%BAtua%20(tamb%C3%A9m%20conhecida%20pelo,esse%20denominado%20por%20se%C3%A7%C3%A3o%20cr%C3%ADtica.

Github – RTC Tiny

https://github.com/evandro-teixeira/RTC_Tiny


Sobre o Autor

 


Evandro Teixeira

Desenvolvedor de sistemas embarcados com mais de 10 anos de experiência, com atuação em diferentes segmentos de mercado tais como eletromédicos, automação industrial, ITS (Sistemas Inteligentes de Transporte) e automotivo.


Eletrogate

22 de março de 2022 Atualizado em: 06 abr 2022

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Componentes Eletronicos

Termistor NTC para controle de temperatura

Eletrogate26 de maio de 2022

Aprenda a medir temperatura com um Termistor NTC junto de um ESP32 utilizando a equação Steinhart-Hart para realizar o cálculo de temperatura detectada pelo termistor NTC.

Componentes Eletronicos

Termistor NTC para controle de temperatura

Eletrogate26 de maio de 2022

Aprenda a medir temperatura com um Termistor NTC junto de um ESP32 utilizando a equação Steinhart-Hart para realizar o cálculo de temperatura detectada pelo termistor NTC.

Módulos Wifi

Placa de Desenvolvimento Arduino Uno WiFi

Eletrogate24 de maio de 2022

Neste post, você conhecerá uma placa que une o melhor das baseadas em ESP8266 com o melhor da família de placas baseadas no ATmega328p: a Uno WiFi.

Módulos Wifi

Placa de Desenvolvimento Arduino Uno WiFi

Eletrogate24 de maio de 2022

Neste post, você conhecerá uma placa que une o melhor das baseadas em ESP8266 com o melhor da família de placas baseadas no ATmega328p: a Uno WiFi.

Projetos

Radar/Sonar Ultrassônico para seus Projetos

Eletrogate19 de maio de 2022

Neste projeto, iremos construir um Radar (‘Radio Detection And Ranging’) ultrassônico com a Arduino e o software Processing. Iremos usar o conhecimento em programação com o sensor ultrassônico no Arduino obtido no post “Sensor Ultrassônico HC-SR04 com Arduino”.

Projetos

Radar/Sonar Ultrassônico para seus Projetos

Eletrogate19 de maio de 2022

Neste projeto, iremos construir um Radar (‘Radio Detection And Ranging’) ultrassônico com a Arduino e o software Processing. Iremos usar o conhecimento em programação com o sensor ultrassônico no Arduino obtido no post “Sensor Ultrassônico HC-SR04 com Arduino”.

Projetos

Levitação Ultrassônica com Arduino

Eletrogate17 de maio de 2022

Não é nenhuma varinha mágica ou encantamento como “Wingardium Leviosa” que você vai precisar para esse projeto. Com um Arduino, um driver de motor ponte H e um sensor de distância ultrassônico HC-SR04 você consegue criar uma máquina capaz de fazer objetos levitarem.

Projetos

Levitação Ultrassônica com Arduino

Eletrogate17 de maio de 2022

Não é nenhuma varinha mágica ou encantamento como “Wingardium Leviosa” que você vai precisar para esse projeto. Com um Arduino, um driver de motor ponte H e um sensor de distância ultrassônico HC-SR04 você consegue criar uma máquina capaz de fazer objetos levitarem.

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!

blog-eletrogate-logo-footer

Rua Rio de Janeiro, 441 - Sala 1301
Centro - Belo Horizonte/MG
CEP 30160-041
*Não temos atendimento físico

ANWAR SLEIMAN HACHOUCHE - ME
CNPJ: 18.917.521/0001-73

Atendimento

(31) 3142-3800

contato@eletrogate.com


Seg a Sex - das 8h às 17h

Institucional

  • Apostilas
  • Quem Somos
  • Privacidade
  • Seja um Redator
  • Trabalhe Conosco

Nos acompanhe

Facebook Instagram Youtube

© ELETROGATE 2022 - Todos os direitos reservados. Termos de uso e Política de privacidade.