Projetos

Controlando o Braço Robótico em MDF via Bluetooth

Eletrogate 29 de agosto de 2023

Introdução

Para aqueles que querem se aventurar pelo mundo da robótica, um bom ponto de partida é montar e experimentar com um braço robótico. A experiência obtida no processo irá ajudar tanto no projeto quanto na programação envolvida e nos detalhes do processo.


Braço Robótico

Existem vários kits de braços robóticos no mercado. A Eletrogate oferece 3 kits: O AS5, o BT3-Mini e o Braço robótico em MDF. Neste artigo, abordaremos o braço robótico em MDF. Para um maior entendimento de conceitos de braços robóticos, recomendo o artigo Braço Robótico: O que são os Graus de Liberdade?.

Este kit contém várias placas em MDF (3 mm) já cortadas com todas as peças da estrutura, parafusos e porcas necessárias. Os 4 servos necessários devem ser comprados  separadamente.

Para montar o kit, recomendo seguir as instruções contidas no manual disponibilizado pela Eletrogate. O manual segue o “estilo Lego”, mostrando as peças a selecionar e indicando com fotos as montagens parciais destas peças.

Para complementar as instruções do manual, gostaria de sugerir as seguintes dicas:

  1. Em boa parte das conexões com parafusos estes são rosqueados em uma das peças em MDF. Sendo assim, é preciso apertá-los com cuidado e delicadeza, para evitar esgarçar o MDF;
  2. Nos parafusos das articulações, é bom deixar um pouco de folga, pois elas devem mover com o mínimo de atrito possível, porém sem muita folga;
  3. Nos parafusos de fixação de motores e das estruturas, deve-se evitar que os motores fiquem com folga, mas com cuidado para não apertar demais;
  4. É recomendado que antes da montagem os servos sejam ligados e posicionados numa posição central. Porém, caso isso não seja feito, é possível ajustar depois.

Dicas para após a montagem:

  1. Com os motores desenergizados, pode-se testar os movimentos manualmente para identificar se está com muito atrito. Caso esteja, identifique a articulação justa e afrouxe um pouco seu parafuso;
  2. Para testar a garra, gire a engrenagem do motor, não a garra. Novamente, em caso da garra não fechar corretamente, verifique os parafusos da garra ou o parafuso que conecta o horn ao motor;
  3. Uma característica deste modelo é a distribuição de peso. Como não existe um contra-peso, o braço tende a inclinar para frente. Além de influenciar na altura da garra, este desnível pode, às vezes, causar travamento do corpo quadrado com a base ou até forçar demais o motor. Para reduzir este problema, basta colocar um “calço” na base para reduzir a inclinação. Isto pode ser feito com qualquer material de aprox. 1 mm (ex: papelão). No meu caso, projetei uma peça impressa em 3D (em vermelho na foto). 
  4. A base não é 100% plana, pois os parafusos e o servo passam um pouco do fundo da base. Uma sugestão para melhorar isso é colocar calços como na foto. No meu caso, usei protetores adesivos anti impacto.

Complementando a dica de inicializar os servos em 90 graus antes da montagem, sugiro fazer as conexões dos horns considerando a configuração da foto abaixo, com o braço e antebraço em 90 graus entre si e com a base e com o braço orientado para a frente da base. Desta forma, o servo da base terá liberdade de 90 para cada lado e os servos horizontal e vertical poderão estender até os limites (menos de 90). Quanto ao servo da garra, sugiro, inicialmente, não aparafusar o horn. Como a engrenagem ligada a ele é parcial e o braço limita a excursão, além de bastante folga na engrenagem, algum ajuste pode ser necessário reposicionando o horn com a engrenagem. Uma vez que a faixa adequada para abertura e fechamento esteja definida, basta aparafusar o horn.

Para quem quiser imprimir o calço em 3D, este foi projetado na ferramenta OpenSCAD. O código está abaixo:

Wall = 1;
CubeLIn = 58;
CubeLOut = CubeLIn+ 2*Wall; 
CubeH = 3;

radius = 30;
CircleH = 1;
MotorD =17.3;

MotorWidth = 12.5;
MotorLength = 23;
MotorDeltaX = 12;
MotorDeltaY = 11.27;
tol = 2;

//linear_extrude(CircleH); {
difference() {
    union() {
        translate([MotorD,CubeLOut/2,CubeH]) linear_extrude(CircleH) circle(radius);


        difference() {
            cube([CubeLOut, CubeLOut, CubeH+CircleH]);
            translate([Wall,Wall,-1]) cube([CubeLIn, CubeLIn, CubeH+1]);
        }
    }
translate([MotorDeltaX-tol/2,CubeLOut/2 - (MotorWidth+tol)/2 ,0])

cube ([MotorLength+tol,MotorWidth+tol, CubeH +CircleH + tol  ]);
}

Geometria do Braço Robótico

Para entendermos os movimentos do braço, precisamos entender a sua geometria. Partindo da posição inicial, se acionarmos o servo de base, ele simplesmente gira o corpo em torno do eixo do motor. O funcionamento da garra também é simples, fechando as pinças conectadas ao servo por engrenagens.

     

Fazendo uma analogia com o braço humano, na figura abaixo podemos dizer que nosso braço robótico possui um braço (vermelho) e um antebraço (verde). Os servos a esquerda e direita do braço, chamados de vertical e horizontal, respectivamente, controlam os ângulos marcados em azul-claro. Ou seja, o servo horizontal controla o ângulo do braço com a base. O servo vertical controla o ângulo do antebraço com relação à horizontal (não com o braço). Além disso, a geometria do braço mantém a garra sempre na horizontal.

Para entendermos como isso é possível, podemos analisar as figuras abaixo. Todas as hastes de mesma cor sempre estarão paralelas entre si durante o movimento.

       

O servo horizontal (figura da esquerda) está conectado diretamente ao braço. Além disso, como este está conectado à peça triangular e a garra garante que a garra sempre estará na horizontal. Ou seja, podemos dizer que este motor controla o ângulo do corpo com o braço.

O servo vertical (figura da direita) aciona um pequeno braço que sempre estará paralelo ao antebraço (em verde). Sendo assim podemos dizer que este motor controla o ângulo do antebraço com relação ao corpo.

Com base nestas relações, usando um pouco de trigonometria, seria possível inclusive calcular as posições estimadas em algum sistema de coordenadas. Questões mecânicas introduziram um erro nestes cálculos, mas pode ser um exercício interessante para experimentos.


Servo

O responsável pelo movimento do nosso braço robótico é o servo. No nosso caso, usaremos o Micro Servo 9g SG90 TowerPro. É um servo pequeno e barato, ideal para aprendizado e situações de pequena carga. Suas engrenagens são de nylon, ao contrário dos seus irmãos maiores, que têm engrenagens de metal.

Cada servomotor contém uma conexão de 3 fios: Vcc, Gnd e sinal. O controle é feito por um sinal que é um pulso PWM (Pulse Width Modulation ou modulação por largura de pulso). Este servo em questão pode se mover entre 0 e 180 graus.


Controle

Para controlar os servomotores, existem algumas opções. A questão aqui é que o consumo destes motores é grande. Logo, a Uno não consegue alimentá-los. Por isso, precisamos de uma fonte externa. Para entender como usar servos com Arduino, veja este artigo: Servo Motor: Conheça Aplicações e Aprenda a Usar.

Além disso, o controle de motores pode gerar ruídos, o que pode ser reduzido por capacitores ou do isolamento dos circuitos de controle da Arduino. Recomendo a leitura do artigo Kit Braço Robótico MDF com Arduino, que aborda bem esta questão, controlando o braço com potenciômetros. Outro artigo interessante é o Braço Robótico com Joystick. É preciso um cuidado maior se o circuito for todo montado numa protoboard. Nos artigos em questão, foi utilizada uma Arduino UNO R3 com um sensor shield. Esse shield oferece algumas vantagens, como já usar uma entrada de fonte externa e já possuir jumpers que permitem conectar o servo direto na shield com a pinagem correta. Cada conexão de servo irá usar um pino digital da Arduino.

No nosso caso, usaremos uma solução diferente: o Módulo PWM PCA9685 I2C – 16 Canais para Servo.


Módulo PWM PCA9685 I₂C - 16 Canais

O uso deste módulo, se comparado com a conexão direta à Arduino (shield ou protoboard), tem algumas vantagens e desvantagens. Para começar, ele permite controlar até 16 servos. A comunicação com a Arduino é feita pelo protocolo I₂C, que usa apenas 2 pinos. O endereço I₂C pode ser alterado na placa, permitindo utilizar até 62 módulos no mesmo circuito, aumentando assim a quantidade de servos a serem controlados (até 992 saídas). O módulo já contém um capacitor de 1000 uF para redução de ruídos. Além disso, por ser um controlador separado, ele reduz a carga de processamento da Arduino, o que pode ser útil em programas mais complexos.

As desvantagens seriam o custo adicional e não permitir uma montagem compacta como o sensor shield. Em especial no braço robótico em MDF, já existe furação para fixar a Arduino na parte traseira, bastando fixar o shield acima dela. No nosso caso, colocamos o módulo numa protoboard a parte.

Na programação, para utilizar o módulo é necessário usar a biblioteca Adafruit_PWMServoDriver.h, ao invés da Servo.h, usada quando conectamos direto à Arduino (com ou sem shield). Os comandos usados são:

  • pwm.begin();    (inicialização)
  • pwm.setPWMFreq(60); (define frequência do pulso)
  • pwm.setPWM(servo, 0, pulso ); (envia o pulso para o PWM)

Módulo Bluetooth HC-06

No blog, já existem artigos controlando o braço robótico com potenciômetros e com joystick. Neste artigo, optamos por apresentar um controle usando o celular com bluetooth. Para isso, usamos o Módulo Bluetooth HC-06. Este módulo contém 4 pinos: Vcc, Gnd, Rx e Tx. Um detalhe importante é que, ao conectar ao Rx, deve ser respeitado o limite de 3.3V. Por isso, é utilizado um divisor resistivo para reduzir o sinal da Arduino de 5V para 3.3V. O Tx também é 3.3V, mas é um nível suficiente para a Arduino reconhecer como “1”.

O módulo HC-06 já foi bem explicado no artigo Módulos Bluetooth HC05 e HC06 para Comunicação com Dispositivos Móveis com Arduino.

Os comandos usados são:

  • serialdobluetooth.available() (indica se algo foi recebido pelo bluetooth)
  • serialdobluetooth.read() (lê o recebido pelo bluetooth)

Arduino Bluetooth Control

Para acessar este módulo no celular, usaremos o App Arduino Bluetooth Control. Este aplicativo oferece várias opções de comunicação. Para simplificar, usaremos 2 delas: Botões e Setas. Temos 4 motores a comandar. Sendo assim, na nossa programação, estipulamos 8 comandos:

  • A — move base para esquerda;
  • a — move base para direita;
  • B — move braço para cima;
  • b — move braço para baixo;
  • C — move braço para frente;
  • c — move braço para trás;
  • D — fecha garra;
  • d — abre garra

Abaixo, vemos a tela principal, com ícones de conexão e configuração na parte superior da tela à direita. Podemos ver as diversas ferramentas disponíveis. Usaremos as setas (Arrow Keys) e os botões (Buttons & Slider)

A opção de botões do aplicativo nos oferece apenas 6 botões. Por isso, o controle da garra foi feito na opção de Setas. Abaixo, podemos ver as telas de setas e botões, acessíveis pela tela principal.

                    

Para configurar o aplicativo, primeiro deve-se clicar na imagem de robô à direita, no topo. No menu, a opção “Keys configuration” (Arrows Keys) permite associar a cada uma das setas um valor. No mesmo menu, é possível configurar os botões em “Command buttons configuration”.

                 

Uma vez configurado e com o circuito pronto e energizado, no topo da tela principal, existe um ícone para conectar. Ao clicá-lo, o HC-06 deve aparecer na lista. Ao clicar no HC-06, a conexão será feita e você já poderá controlar o braço robótico.

No programa, cada comando altera o ângulo do respectivo servo em 5 graus.


Montagem e Ajustes

O circuito e suas conexões podem ser vistos na figura abaixo. As conexões dos servos ao módulo PWM foram conectadas nas entradas 0 a 3 na seguinte ordem: Base, Vertical, Horizontal, Garra.

O diagrama acima não mostra as conexões dos servos. Estes conectores devem ser conectados diretamente ao módulo PWM, respeitando a posição dos fios: marrom é GND, vermelho V+ e laranja PWM. Os servos são ligados nas posições 0 a 3 na seguinte ordem: base, vertical, horizontal, garra. O conector da garra precisa ser conectado com o cabo extensor (sinal em branco, não laranja). As conexões podem ser vistas na foto da montagem mais abaixo.

Cabe aqui uma observação sobre a protoboard de 830 pinos e a alimentação do circuito. Esta protoboard tem 2 pares de alimentação no topo e abaixo. Porém, cada fileira também é dividida no meio. Neste circuito usamos uma alimentação externa nas fileiras de cima, unidas por dois fios. Estas alimentam apenas os servos através do módulo PWM.

Na parte inferior direita, a alimentação vem da Arduino, que, por sua vez, vem da porta USB do PC, quando conectado para programação e testes. Porém, o terra é comum com a fonte conectada com a protoboard, através de conexão de fio na protoboard.

Para a alimentação da fonte da protoboard, utilizei uma fonte de celular de 5V / 400 mA conectada à entrada USB. Funcionou, porém seria recomendado uma fonte capaz de 1 A. Cada servo consome de 10 mA a 250 mA em carga nominal máxima. Porém, se travarem, podem consumir até 0.7 A. Se a montagem do braço robótico estiver ok, a carga é bem baixa e não haverá travamento. A exceção seria a garra, caso estava segurando um objeto com muita força.

Esta fonte para protoboard permite também entrada de uma fonte de 7-10 V via plug P4.  Porém, é preciso tomar cuidado com a entrada, pois, se ultrapassado o limite de 10 V, a fonte pode falhar e repassar uma tensão alta para a saída, queimando os servos (experiência própria com bateria de 12 V). Por isso, recomendo usar uma fonte de 5 volts, por segurança.

Uma alternativa, que acredito ser a mais segura,  seria alimentar diretamente o conector do módulo PWM com Fonte 5V + Conector Adaptador Plug P4 Femea com Borne KRE.

Abaixo, segue foto da protoboard usando a fonte para protoboard MB102.

Antes de começar a usar o braço robótico, para evitar danos, sugiro ligar cada motor individualmente para verificar seus limites e fazer os ajustes necessários. No programa, existem arrays com os limites inferior e superior (servo_limite_inf e servo_limite_sup). Existe também uma array com os valores iniciais quando a Arduino é ligada (servo_inicial). Os limites podem ser alterados para 0 e 180 durante a calibragem e identificação dos valores corretos.

Todos estes valores foram obtidos por experimentação, testando um motor de cada vez e identificando os limites de movimento que a garra permite. Na montagem, sugeri que os servos fossem iniciados em 90 graus. Mas, dependendo da posição do braço na montagem, pode ser necessário reconectar os horns. Lembre que os servos têm o limite de 0 a 180.

Reposicionar os servos da garra e da base é simples, pois os horns são de fácil acesso. Basta dar o comando do servo para uma posição central (90?), desparafusar o horn sem girar o motor, reposicionar o horn numa posição adequada (~metade do movimento) e reaparafusar.

Para os servos de movimento vertical e horizontal o procedimento é semelhante, mas se faz necessário desparafusar a lateral do corpo do braço antes, para ter acesso ao parafuso do horn. Para o servo vertical são dois parafusos na base da lateral. Para o servo horizontal, é preciso  desaparafusar os dois da base da lateral e um do braço.

Abaixo é possível ver os servos vertical e horizontal, respectivamente, já com a lateral desconectada e movida para uma posição onde os parafusos dos horns estão acessíveis. Perceba o ângulo de 90 graus dos braços conectados aos horns com relação a lateral da base. Ao final, basta reencaixar e aparafusar novamente. 

Este procedimento só é necessário caso o posicionamento correto não tenha sido feito durante a montagem e se o movimento dos servos estiver limitado. Caso contrário, basta ajustar a posição inicial e os limites no programa.

Um vez que todos os servos estejam conectados adequadamente, mova cada um até os limites que o braço permite e atualize os valores das arrays de limites e posição inicial citadas acima.

Para melhor entendimento do código, segue uma lista das funções e suas atribuições:

  • int leComando() : Lê e retorna um comando recebido do módulo Bluetooth;
  • void processaComando(int cmd) : Recebe um comando e executa o mesmo;
  • void moveServos() : move todos os servos para a posição designada na array setservoTarget;
  • void moveToAngle(int servo, float angle) : Move um servo para o angulo designado via comando;
  • int angleToPulse(int ang) : converte o angulo em graus para o pulso necessário a ser enviado para o servo;
  • void setservoTarget(int Servo, float target) : Muda o angulo alvo, respeitando os limites definidos
/* Programa de controle de braço robótico em MDF via Bluetooth
   Blog Eletrogate - https://blog.eletrogate.com/
   Arduino Uno - IDE 2.1.1
   Mauro Vianna   11/julho/2023
*/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <SoftwareSerial.h> //Biblioteca para conectar com o bluetooth (já vem instalado), não precisa baixar

SoftwareSerial serialdobluetooth(8,9); // Portas para o serial do bluetooth (RX, TX)

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); // objeto de controle PWM dos servos

#define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)

uint8_t numberOfServos = 4;

// Identificação dos servos
#define SV_BASE 0
#define SV_VERTICAL 1
#define SV_HORIZONTAL 2
#define SV_GARRA 3
#define NUM_SERVOS 4

// Arrays dos servos
float servo_target[NUM_SERVOS];                           // posição alvo de movimento
int servo_limite_inf[NUM_SERVOS] = {0, 45, 90,30};         // Limite inferior do ângulo do servo
int servo_limite_sup[NUM_SERVOS] = {180, 140, 175, 160};   // Limite superior do ângulo do servo
int servo_inicial[NUM_SERVOS] = {90, 120, 90, 30};          // Posição inicial do ângulo do servo

float delta = 5; // Movimento do ângulo por cada comando

// Definição dos comandos
#define CMD_NULO 0
#define CMD_ESQ 'A'
#define CMD_DIR 'a'
#define CMD_AVANCA 'B'
#define CMD_RECUA 'b'
#define CMD_SOBE 'C'
#define CMD_DESCE 'c'
#define CMD_ABRE 'D'
#define CMD_FECHA 'd'

int comando;  // comando a ser executado
//int valordobluetooth; // Variável que vai ler o valor enviado pelo bluetooth 

// Inicialização 
void setup() {
  serialdobluetooth.begin(9600);  // Início da serial do bluetooth
  Serial.begin(9600);             // Início da serial com o PC
  pwm.begin();                    // Inicialização do PWM
  pwm.setPWMFreq(60);
  delay(10);
  
  // Move servos para posição inicial
  for (int i = 0; i<= numberOfServos; i++ ) {
    servo_target[i] = servo_inicial[i];
    Serial.print("Alvo: ");Serial.print(i); Serial.print(" : ");Serial.println(servo_inicial[i]);
  }
  
  moveServos();
  
}

// Loop principal : Lê comando via Bluetooth e processa
void loop() {
  // put your main code here, to run repeatedly:
//  moveToAngle(0,90);

  comando = leComando();
  if (comando != CMD_NULO) {
    processaComando(comando);
  }
  //delay(100);
  moveServos();
}

// Faz a leitura de comando do bluetooth. Na ausência de comando retorna CMD_NULO
int leComando() {
  if (serialdobluetooth.available()) //Se o bluetooth estiver funcionando, vai ser lido o "valor", para reproduzir o comando
  {
    return serialdobluetooth.read();
  }
  else {
    return CMD_NULO;
  }
} 

// Processa cada comando
void processaComando(int cmd) {
  int garra;
  switch (cmd) {
    case CMD_ESQ:
      // statements
      setservoTarget(SV_BASE,servo_target[SV_BASE] + delta);
      Serial.print("<< base "); 
      Serial.print(" | ");
      Serial.println(servo_target[SV_BASE]);
      break;
    case CMD_DIR:
      setservoTarget(SV_BASE,servo_target[SV_BASE] - delta);
      Serial.print("base >>"); 
      Serial.print(" | ");
      Serial.println(servo_target[SV_BASE]);
      break;
    case CMD_SOBE:
      setservoTarget(SV_VERTICAL,servo_target[SV_VERTICAL] - delta);
      Serial.print("sobe");
      Serial.print(" | ");
      Serial.println(servo_target[SV_VERTICAL]);
      break;
    case CMD_DESCE:
      setservoTarget(SV_VERTICAL, servo_target[SV_VERTICAL] + delta);
      Serial.print("desce");
      Serial.print(" | ");
      Serial.println(servo_target[SV_VERTICAL]);
      break;
    case CMD_AVANCA:
      setservoTarget(SV_HORIZONTAL,servo_target[SV_HORIZONTAL] - delta);
      Serial.print("avança >>");
      Serial.print(" | ");
      Serial.println(servo_target[SV_HORIZONTAL]);
      break;
    case CMD_RECUA:
      setservoTarget(SV_HORIZONTAL, servo_target[SV_HORIZONTAL] + delta);
      Serial.print("<< recua");
      Serial.print(" | ");
      Serial.println(servo_target[SV_HORIZONTAL]);
      break;
    case CMD_ABRE:
      setservoTarget(SV_GARRA, servo_target[SV_GARRA] - delta);
      Serial.print("<< abre >>");
      Serial.print(" | ");
      Serial.println(servo_target[SV_GARRA]);
      break;
    case CMD_FECHA:
      // statements
      setservoTarget(SV_GARRA, servo_target[SV_GARRA] + delta);
      Serial.print(">> fecha <<");
      Serial.print(" | ");
      Serial.println(servo_target[SV_GARRA]);
      break;
    default:
      break;
  }
}

// Move todos os servos
void moveServos() {
    for (int i = 0; i<= numberOfServos; i++ ) {
    moveToAngle(i,servo_target[i]);
  }
}
// Move servo para angulo designado enviando o pulso correspondente
void moveToAngle(int servo, float angle) {
  pwm.setPWM(servo, 0, angleToPulse(angle) );
}
// Converte o valor do ângulo para o pulso correspondente
int angleToPulse(int ang){
   int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max 
   return pulse;
}

// Muda o ângulo alvo do servo, respeitando os limites configurados
void setservoTarget(int Servo, float target) {
  int valor;
  valor = target;
  valor = min(valor,servo_limite_sup[Servo]);
  valor = max(valor,servo_limite_inf[Servo]);
  servo_target[Servo] = valor;
}

Abaixo, um vídeo curto mostrando a operação do braço robótico:


Possibilidades

Existem várias opções de como usar este tipo de controle para executar comandos. Usamos o controle direto dos servos. Porém, cada comando poderia acionar movimentos para determinadas posições, ou até sequências de movimentos. Por exemplo, um comando poderia voltar o braço para posição inicial. Outro poderia ser uma sequência de movimentos para pegar um objeto X. E outro uma sequência para soltar em uma posição Y. Ou, quem sabe, até uma “dancinha”?

O controlador PWM usado permitiria até controlar mais braços robóticos deste tipo (até 4) com a mesma Arduino.

Os comandos executam um movimento de 5 graus. É possível mudar isso mudando a variável delta para um movimento mais suave, porém mais lento. Outra opção para suavizar o movimento seria mover por passos menores. Por exemplo, ao dar um comando de alteração de 5 graus, o programa poderia fazer uma repetição de movimentos menores (5 passos de 1 grau?) para suavizar.

O aplicativo Android Bluetooth Controller possui outros recursos interessantes a explorar. Na tela de botões, ao girar o celular existe um slider. Em teoria este poderia ser usado para controlar a garra, mas demandaria programação adequada. A ferramenta Terminal permite também enviar comandos e receber mensagens da Arduino. Pode ser interessante para implementar comandos mais complexos.


Conclusão

Vimos, neste artigo, o uso do braço robótico em MDF de uma forma alternativa a outros artigos, usando um controlador de servos e controle por bluetooth. Este braço permite uma ampla gama de experimentações, sendo um excelente ponto de partida para aqueles que estão iniciando suas aventuras com robótica. Abordaremos mais aspectos deste kit em artigos futuros.


Sobre o Autor


Mauro Roberto

Formado em engenharia elétrica com ênfase em eletrônica e sistemas pela PUC-RJ. Pós graduado em Teoria de Controle e Estatística. Atuou vários anos em desenvolvimento de sistemas software. Hobbysta em impressão 3D, arduino e robótica.


Eletrogate

29 de agosto de 2023

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.

Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!