MJRoBot, o(s) filme(s)!

A partir de agora, você poderá também acompanhar meus tutoriais em vídeo. Os tres primeiros já estão no Youtube:

Vídeo 1: “Introdução ao Arduino”

 

Vídeo 2: “Introdução ao Raspberry Pi”

 

Vídeo 3: “Projetos com Arduino, Raspberry, ESP, Raspberry & IoT.”

 

Espero que gostem!

Saludos desde el sur del mundo!

Abração

Marcelo

 

Anúncios

IoT feito simples: Controlando servos com o NodeMCU e o Blynk

Neste tutorial, exploraremos como controlar um servo através da Internet. Para isso, lançaremos mão de uma importante dupla de dispositivos no mundo do IoT:
o NodeMCU ESP12-E e o Blynk.

Começaremos por aprender como conectar um servo com o NodeMCU, como controlá-lo localmente com um potenciômetro, como ver sua posição em um display e finalmente como controlá-lo através da internet usando um smartphone.

O diagrama de blocos abaixo nos dá uma visão geral do projeto final.

Servo Control Block Diagram

 

E o vídeo, mostrará o projeto funcionando:

1. BoM (Lista de materiais)

BoM
Valores em USD, apenas para referência.

2. Conectando o servo e o potenciômetro

IMG_1573.jpg

 

A primeira coisa que faremos é configurar o NodeMCU para lidar com o Servo, controlando-o através de um potenciômetro de 10K ohm.

Servo-Pot Block Diagram

Cuidado! O NodeMCU é alimentado com 5V, mas todos os seus GPIOs trabalham com um nível de 3.3V.

Dividiremos os barramentos de alimentação do Breadboard, deixando um para 5V e o outro para 3.3V. Para isso, usaremos uma fonte de alimentação específica para Breadboards como a mostrada no diagrama elétrico abaixo:

Servo Circuit 1

NOTA: Durante a fase de desenvolvimento (PC ligado à NodeMCU via porta USB), não é necessário ligar o pino Vin a + 5V (fio vermelho no diagrama), uma vez que a energia será fornecida pelo computador. Deixe-o desconectado.

Para o controle do servo, usaremos a biblioteca: Servo.h :

#include <Servo.h>   // Include the library
Servo servo1;        // Name it "servo1"
#define servo1Pin D2 // Define the NodeMCU pin to attach the Servo

Durante setup(), a variável servo1 deve ser iniciada:

servo1.attach(servo1Pin);

O potenciômetro de 10K funcionará como um divisor de tensão, alterando o nível da entrada analógica no NodeMCU (A0) de 0 a 3.3V. Internamente, o ADC de 10 bits (Conversor Analógico-Digital) gerará um valor digital correspondente (de 0 a 1023), armazenado na variável potReading, equivalente à entrada de tensão analógica.

potReading = analogRead(A0);

Devemos “mapear” esse valor digital, para que a saída digital modulada por largura de pulso (PWM) do pino D2 varie de 0 a 180 (variável servo1Angle).

servo1Angle = map(potReading, 0, 1023, 0, 180);

O servo girará de 0 a 180 graus, utilizando-se do comando abaixo:

servo1.write(servo1Angle); 

A posição do Servo em graus será exibida, durante esta fase de teste, no Monitor Serial:

Serial.println(servo1Angle);

O codigo completo para os testes com o servo, poderá ser descarregado desde meu GitHub:

NodeMCU_Servo_Control_Test

O vídeo abaixo mostra os testes sendo realizados com o servo:

3. Instalando um display

Let's Display!

 

Esta bem utilizar o Serial Monitor durante os testes, mas o que acontecerá quando você estiver utilizando seu protótipo longe de seu PC em modo autônomo? Para isso, instalaremos um display do tipo OLED, o nosso velho conhecido: SSD1306, cujas principais características são:

  • Tamanho da tela: 0.96 “
  • Comunicação Serial I2C IIC SPI
  • 128X64
  • Display de caracteres na cor branca

Conecte os pinos do OLED ao NodeMCU, conforme descritos abaixo e no diagrama elétrico acima:

  • SDA    ==> D1 (5)
  • SCL * ==> D2 (4) * Você também poderá encontrar “SDC” ao invés de SCL
  • VCC   ==> 3.3V ou 5V
    GND ==> GND

O SSD1306 pode ser alimentado tanto com 5V quanto com 3.3V. Usaremos 3.3V fornecidos externamente para não sobrecarregar o NodeMCU.

Depois de conectar o OLED, deveremos baixar e instalar sua biblioteca no IDE do Arduino. Usaremos a biblioteca gráfica desenvolvida por Daniel Eichhorn.  Entre no link abaixo e descarregue a biblioteca, instalando-a no IDE do Arduino:

https://github.com/squix78/esp8266-oled-ssd1306

Certifique-se de usar a versão 3.0.0 ou maior!

Depois de reiniciado o IDE, a biblioteca já deverá estar instalada.

A biblioteca suporta o protocolo I2C para acessar a modulo OLED, usando a biblioteca Wire.h:

#include <Wire.h>   
#include "SSD1306.h"
SSD1306  display(ADDRESS, SDA, SDC);

Listaremos apenas algumas API mais importantes, as quais serão utilizadas com o OLED.

A lista completa poderá ser encontrada no GITHub fornecido anteriormente neste tópico.

A. Controle de exibição do display:

void init(); // Initialise the display
void displayOn(void); // Turn the display on
void displayOff(void); // Turn the display offs
void clear(void); // Clear the local pixel buffer
void flipScreenVertically(); // Turn the display upside down

B. Operações com texto:

void drawString(int16_t x, int16_t y, String text); // (xpos, ypos, "Text")
void setFont(const char* fontData);  // Sets the current font.

Fonts disponíveis:

  • ArialMT_Plain_10,
  • ArialMT_Plain_16,
  • ArialMT_Plain_24

IMG_1582.jpg

Uma vez que tenhamos instalado o OLED e sua biblioteca, devemos utilizar um programa simples para testá-lo. Digite o código abaixo em seu IDE, o resultado deverá ser como o mostrado na foto acima:

/*NodeMCU */
#include <ESP8266WiFi.h>

/* OLED */
#include "SSD1306Wire.h"
#include "Wire.h"
const int I2C_DISPLAY_ADDRESS = 0x3c;
const int SDA_PIN = 0;
const int SCL_PIN = 2;
SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN);

void setup () 
{
  Serial.begin(115200); 
  displaySetup();
}

void loop() 
{ 
}

/* Initiate and display setup data on OLED */
void displaySetup()
{
  display.init();         // initialize display
  display.clear();        // Clear display
  display.display();      // Put data on display
  
  Serial.println("Initiating Display Test");
  
  display.setFont(ArialMT_Plain_24);
  display.drawString(30, 0, "OLED");  // (xpos, ypos, "Text")
  display.setFont(ArialMT_Plain_16);
  display.drawString(18, 29, "Test initiated");
  display.setFont(ArialMT_Plain_10);
  display.drawString(10, 52, "Serial BaudRate:");
  display.drawString(90, 52, String(11500));
  display.display();  // Put data on display
  delay (3000);
}

Se desejar, o codigo acima poderá ser descarregado de meu GitHub:

NodeMCU_OLED_Test

4. Mostrando a posição do servo no OLED

Showing the Servo Position in the OLED Display

 

Agora “misturemos” os 2 códigos anteriores, assim poderemos não apenas controlar a posição do servo utilizando-se do potenciômetro, mas também ver sua posição na tela do OLED.

O código completo poderá ser baixado desde meu GitHub:

NodeMCU_Servo_Control_Test_OLED

E o resultado verificado no video abaixo:

5. Criando a App Blynk para o controle do servo

IMG_1593.jpg

 

Basicamente, precisaremos alterar o código anterior, incluindo a parte referente ao Blynk mostrada a seguir:

#include <BlynkSimpleEsp8266.h>
char ssid [] = "YOUR SSID";
char pass [] = "YOUR PASSWORD";
char auth [] = "YOUR AUTH TOKEN"; // Servo Control Project

/* Reads slider in the Blynk app and writes the value to "potReading" variable */
BLYNK_WRITE(V0) 
{
  potReading = param.asInt();
}

/* Display servo position on Blynk app */
BLYNK_READ(V1) 
{
  Blynk.virtualWrite(V1, servo1Angle);
}

void setup () 
{
  Blynk.begin(auth, ssid, pass);
}

void loop() 
{
  Blynk.run();
}

Deveremos definir um pino virtual V0, onde o Blynk irá “escrever” (ou “comandar”) a posição de servo, da mesma forma que fizemos com o potenciômetro. Na app do Blynk, usaremos um “Slider” (com saída definida de 0 a 1023) que usaremos para comandar a posição do servo.

Outro pino virtual, V1, será utilizado para “ler” a posição do servo, da mesma forma que fazemos com o OLED. Na app do Blynk, usaremos um “Display” (com saída definida de 0 a 180) onde mostraremos a posição do servo.

Blynk

As fotos acima mostram as telas referents ao app do Blynk.

Voce poderá descarregar o programa complete desde meu GitHub:

NodeMCU_Servo_Ctrl_Blynk_EXT

6. Conclusão

Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrônica, robótica e do IoT!

Visite o meu depositário de arquivos no GitHub para obter os arquivos atualizados:

IoT-Servo-Control

Não deixem de visitar e seguir minha página: MJRoBot.org no Facebook

Saludos desde el sur del mundo!

Até o próximo post!

Obrigado

Marcelo

Deteção de cores com o Arduino

Neste tutorial, exploraremos como ler cores usando um Arduino e sensores como o TCS 3200. A idéia será detectar a cor de um objeto, exibindo-a em um LCD. Este tutorial é a primeira parte de um projeto maior, um braço robótico que decide que operação executar a partir da cor de uma peça.

O diagrama de blocos abaixo mostra os principais componentes:

Color Detector Block Diagram

O vídeo abaixo mostra como ficará o projeto final:

1: Lista de materiais (BoM)

Os links e preços abaixo são apenas para referência.

  1. Arduino Nano (US$ 8.00)
  2. TCS3200 Color Sensor Module (US$ 9.00)
  3. IIC/I2C/TWI 1602 Serial Blue Backlight LCD Module (US$ 8.00)
  4. Breadboard (US$ 2.00)
  5. Cables

2: O sensor TSC 3200

The TSC 3200 Color Sensor

Como descrito en seu Datasheet, O TCS3200 é um conversor programável de luz (cor) em frequência que combina fotodiodos de silício configuráveis e um conversor de corrente em frequência, tudo encapsulado em um único circuito integrado do tipo CMOS.

A saída é um sinal do tipo “onda quadrada” (ciclo de trabalho de 50%) cuja freqüência é diretamente proporcional à intensidade da luz (irradiance). A frequência de saída pode ser escalonada por um dos três valores predefinidos através de dois pinos de entrada de controle (S0 e S1).

Entradas e saída digitais permitem interface direta com um microcontrolador ou outros circuitos lógicos.
TSC3200 Diagram
Output enable (OE) coloca a saída no estado de alta impedância para a partilha de múltiplas unidades de uma linha de entrada do microcontrolador. No TCS3200, o conversor de luz em frequência lê uma matriz 8 x 8 de fotodíodos. O OE (Enable) deve ser conectado a GND (LOW).
  • 16 fotodiodos têm filtros azuis,
  • 16 fotodiodos têm filtros verdes,
  • 16 fotodiodos têm filtros vermelhos e
  • 16 fotodiodos são claros sem filtros.

Os pinos S2 e S3 são usados para selecionar qual grupo de fotodíodos (vermelho, verde, azul ou claro) está ativo. Os fotodiodos têm um tamanho de 110 μm x 110 μm e estão em centros de 134 μm.

O Sensor deve ser alimentado entre 2.7 e 5.5VDC. Usaremos a saída 5V do Arduino para alimentar o sensor.

Para usar corretamente o sensor, vamos instalar um pequeno anel de borracha para isolar o sensor da luz lateral. Eu usei cola quente para corrigi-lo.

Sensor with ring

3: Conectando o HW

Connecting the HW
  1. Instale o Arduino Nano no BreadBoard
  2. Conecte a saída de 5V e GND do Nano 5Va ambos Power Rails do BreadBoard
  3. Conecte o sensor TSC3200 como descrito abaixo:
    • S0     ==> Nano pin D4
    • S1     ==> Nano pin D5
    • S2     ==> Nano pin D6
    • S3     ==> Nano pin D7
    • OUT ==> Nano Pin D8
    • EN    ==> GND
    • VCC  ==> +5V
    • GND ==> GND
  4. Conecte o I2C LCD 2/16 Serial Display como abaixo:
    • SDA ==> Nano Pin A4
    • SCL ==> Nano Pin A5

4: O código do Arduino

The Arduino Code

A primeira coisa a definir é a escala de freqüência a ser utilizada, tal como definida na tabela mostrada acima. Os pinos S0 e S1 são usados para isso. A escala da freqüência de saída é útil para otimizar as leituras de sensores para vários contadores de freqüência ou microcontroladores. Definiremos S0 e S1 em HIGH (100%), funcionou bem com meu Nano. Já observei em alguns projectos com o UNO, a frequência escalonada em 20%. Teste para ver o melhor em seu caso.

  digitalWrite(s0,HIGH);
  digitalWrite(s1,HIGH);

A próxima coisa a fazer é selecionar a cor a ser lida pelo fotodíodo (vermelho, verde ou azul), usamos os pinos de controle S2 e S3 para isso. Como os fotodiodos são conectados em paralelo, o ajuste de S2 e S3 como LOW ou HIGH em combinações diferentes, permite que você selecione diferentes fotodiodos, como mostrado na tabela acima e definidos no código abaixo:

void readRGB() 
{
  red = 0;
  grn = 0;
  blu = 0;
  int n = 10;
  for (int i = 0; i < n; ++i)
  {
    //read red component
    digitalWrite(s2, LOW);
    digitalWrite(s3, LOW);
    red = red + pulseIn(outPin, LOW);
 
    //read green component
    digitalWrite(s2, HIGH);
    digitalWrite(s3, HIGH);
    grn = grn + pulseIn(outPin, LOW);
 
    //let's read blue component
    digitalWrite(s2, LOW);
    digitalWrite(s3, HIGH);
    blu = blu + pulseIn(outPin, LOW);
  }
  red = red/n;
  grn = grn/n;
  blu = blu/n;
}

Observe que no código acima,  leremos algumas vezes cada um dos componentes RGB, tomando uma média, para que com isso possamos reduzir o erro se algumas leituras forem ruins.

Uma vez de posse dos 3 componentes (RGB), deveremos definir a qual cor equivale. A maneira de fazê-lo é “calibrando-se” previamente o projeto. Você pode usar tanto papel quanto objetos com cores conhecidas e assim ler os 3 componentes gerados por este objeto.

Você pode começar com o meu set-up, mudando os parâmetros para o seu nível de luz:

void getColor()
{ 
 readRGB();
      if (red > 8 && red < 18 && grn > 9 && grn < 19 && blu > 8 && blu < 16) color = "WHITE";  else if (red > 80 && red < 125 && grn > 90 && grn < 125 && blu > 80 && blu < 125) color = "BLACK";  else if (red > 12 && red < 30 && grn > 40 && grn < 70 && blu > 33 && blu < 70) color = "RED";  else if (red > 50 && red < 95 && grn > 35 && grn < 70 && blu > 45 && blu < 85) color = "GREEN";  else if (red > 10 && red < 20 && grn > 10 && grn < 25 && blu > 20 && blu < 38) color = "YELLOW";  else if (red > 65 && red < 125 && grn > 65 && grn < 115 && blu > 32 && blu < 65) color = "BLUE";
 else color = "NO_COLOR";
}

Como você pode ver acima tenho predefinido 6 cores: Branco, Preto, Vermelho, Verde, Amarelo e Azul.

À medida que a luz ambiente diminui, os parâmetros tendem a aumentar de valor.

Dentro do loop (), definimos que as leituras são mostradas no LCD a cada 1 segundo.

O código completo pode ser encontrado no meu GitHub:

https://github.com/Mjrovai/Color-Detector

5: Conclusão

Como sempre, espero que este projeto possa ajudar outras pessoas a encontrar o seu caminho no excitante mundo da eletrônica, robótica e do IoT!

Por favor, visite o meu GitHub para arquivos atualizados: Color Detector

Não deixem de se inscrever no congresso on-line: Tudo sobre IoT, que acontecerá entre 5 e 8 de junho. Estarei fazendo a palestra: “A revolução Maker e o retorno dos dinossauros!” Nos vemos lá!
Iot Congress Banner MR
Saludos desde el sur del mundo!
Até o próximo post!
Um abraço e obrigado.
Marcelo

ArduFarmBot, the book is alive!

A versão em inglês do ArduFarmBot já está na Amazon, mas não se esqueça que a versão original em português também poderá ser adquirida no link: ArduFarmBot (Portuguese Edition)

 

The english version of ArduFarmBot is alive at Amazon.com! You can get it, clicking the bellow banner:

Amazon_book

The book uses the electronic controller ArduFarmBot as a basis for learning how to work in both HW and SW, with: a) LCD and OLED type displays; b) LEDs and buttons; c) Activation of pumps and lamps via relays and d) Sensors such as: DHT22 (temperature and relative air humidity), DS18B20 (soil temperature), YL69 (soil moisture) and LDR (luminosity).

book_pages_2.png

All key stages of the project are documented in detail through explanatory texts, block diagrams, high-resolution color photos, electrical diagrams using Fritzing application, complete codes stored in GitHub and YouTube videos.

book_pages_3

Two versions of the electronic controller ArduFarmBot are developed in detail in the book. From capture of data coming from a garden, such as air and soil temperature, relative humidity, soil moisture and luminosity, the ArduFarmBot helps to control when a crop should receive heat and water. Control will happen automatically, locally and remote via internet

The book is divided into 3 parts.

In the first part, the Arduino Nano is the starting point for development of a local version of ArduFarmBot, that can be controlled both, manually and automatically.

book_pages_4

In the second part, the book dives into automation design, introducing remote operation through the creation of a webpage. The ESP8266-01 is used for Wi-Fi connection, sending data to an important web service in the field of IoT, the ThingSpeak.com.

book_pages_5

In the third part, a second version of ArduFarmBot is developed, introducing the NodeMCU ESP8266-12E, a powerful and versatile IoT device, which replaces both the Arduino Nano and the ESP8266-01, used in the earlier parts of the book.

book_pages_6

In this last part of the book, a new service platform of the IoT universe, the Blynk, is also explored.

book_pages_7

Download the book, give it a review and please use the message board here to give us any comment, suggestion or critic!

Thanks a lot

Saludos desde el sur del mundo!

Marcelo

 

Robô controlado por voz via WiFi

Em meu último tutorial: Controle ativado por voz com Android e NodeMCU, exploramos como desenvolver nossa própria App em um smartphone Android para controlar localmente (usando botões ou voz) dispositivos domésticos inteligentes. Que tal agora, em vez de dispositivos domésticos controlarmos motores? E melhor ainda, que tal ter esses motores movendo um robô? Pois isso, é exatamente o que desenvolveremos aqui, um robô controlado por voz via WiFi e utilizando como microcontrolador nosso velho amigo, o NodeMCU!

O diagrama de blocos abaixo nos dá uma geral sobre o projeto que desenvolveremos aqui:

WiFi_Robot_Block_Diagram

e o filme nos mostra como ficará o projeto:

Por favor, considere que um de meus motores estava com muito pouco torque. Apesar de o resultado parecer estranho, o projeto funciona a contento. Assim que mudar o motor, atualizarei o vídeo. Obrigado.

1: Lista de materiais (BoM)

Valores em USD, apenas para referência.

  1. NodeMCU ESP8266-12E ($8.79)
  2. 400-point Experiment Breadboard Breadboard ($ 4.97)
  3. H-Bridge L293D ($2.17)
  4. Motor Robot Car Chassis Kit ($13.00)
  5. Male-Female Dupont Cables ($1.00)
  6. Portable Charger 5VDC 3000mAh Power Bank ($10.00)
  7. Bateria 9V DC

….. e qualquer telefone ou tablet Android!

2: A Ponte-H L293D

  L293D
Para “drivar” os motores usaremos o L293D.

De acordo com seu Datasheet, o L293D é um controlador do tipo half-H quádruplo de alta corrente. O L293D foi projetado para fornecer correntes bidirecionais de até 600 mA em tensões variando de 4,5 V a 36 V.

Usaremos o CI L293D diretamente com o NodeMCU, em vez de um Shield, como se vê mais comumente em projetos no mercado.

Pois bem, nosso robô terá duas rodas, acionadas por 2 motores DC:

  • Motor esquerdo (LEFT)
  • Motor direito (RIGHT)

NodeMCU_L293D_Block_Diagram

Ligaremos os motores ao L293D e este ao NodeMCU, como mostra o diagrama em blocos anterior, onde 6 de seus GPIOs comandarão esses motores.

int rightMotor2 = 13;   // D7 - right Motor -
int rightMotor1 = 15;   // D8 - right Motor +
int leftMotor2 = 0;     // D3 - left Motor - 
int leftMotor1 = 2;     // D4 - left Motor +
int eneLeftMotor = 12;  // D6 - enable Motor Left
int eneRightMotor = 14; // D5 - enable Motor Right

Por exemplo, para mover o robô para a frente,  girando o motor esquerdo (LEFT) no sentido apropriado, você deve colocar:

  • HIGH no pino D4 (motor esquerdo +) e
  • LOW no pino D3 (motor esquerdo -)

Para o motor direito (RIGHT) você deve fazer o oposto:

  • HIGH no pino D8 (motor direito +) e
  • LOW no pino D7 (motor esquerdo -)

The H-Bridge L293D

Devido à maneira como meus motores são montados, a combinação acima irá girar ambos motores no mesmo sentido, “empurrando” o robô para a frente.

Robot direction.jpg

O diagrama acima define (ou melhor, convenciona) como o robô deverá se mover. Isso é importante para a definição adequada de suas variáveis.

Para controlar a H-Bridge corretamente, você também deverá trabalhar com os pinos de habilitação (“enable”). No exemplo anterior onde o robô se move para a frente, além dos 4 GPIOs discutidos, o robô só funcionaia se os pinos de habilitação (eneLeftMotor e eneRightMotor) estiverem ambos em HIGH. Você poderá conectar esses pinos do L293D (1 e 9) diretamente a + VCC e esquecê-los. Eu não gosto disso, porque se voce necessita por exemplo, parar rapidamente seu robô, esses pinos deveriam estar em necessariamente em LOW. Além disso, associar os pinos de habilitação a saídas PWM do NodeMCU, permitirá também controlar a velocidade do motor. Em nosso exemplo, usaremos estes pinos apenas com valores digitais tais como HIGH e LOW, o que ajustará a velocidade para MAX e ZERO, respectivamente.

Asim, para se criar uma função que conduza nosso robô para a frente, devemos escrever um código como este:

void forwardMotor(void)   
{
  digitalWrite(eneLeftMotor,HIGH);
  digitalWrite(eneRightMotor,HIGH);
    
  digitalWrite(leftMotor1,HIGH);
  digitalWrite(leftMotor2,LOW);
  digitalWrite(rightMotor1,HIGH);
  digitalWrite(rightMotor2,LOW);
}

3: Movendo o robô em outras direções

Na etapa anterior, aprendemos como podemos mover o robô para a frente, pensemos agora como movê-lo em outras direções.
Definamos 5 possíveis comandos:
  1. STOP: Pare
  2. LEFT: Vire à esquerda
  3. RIGHT: Vire à direita
  4. REVERSE: Dê marcha à ré
  5. FORWARD: Vá para a frente

O primeiro comando “STOP” é simples de realizar. Todas as entradas da H-Bridge devem estar em LOW, desta forma os motores não se moverão:

void stopMotor(void)   
{
  digitalWrite(eneLeftMotor,LOW);
  digitalWrite(eneRightMotor,LOW);

  digitalWrite(leftMotor1,LOW);
  digitalWrite(leftMotor2,LOW);
  digitalWrite(rightMotor1,LOW);
  digitalWrite(rightMotor2,LOW);
}

Da mesma forma pensemos em fazer o robô tomar outra direção, digamos que “virar à ESQUERDA”. Considere que o robô está indo para a frente, se queremos virar à esquerda podemos pensar em duas situações:

  1. Parar o motor ESQUERDO, mantendo o motor DIREITO no sentido a frente (Forward): o robô executará uma trajetória de arco para a esquerda
  2. Inverter o sentido do motor ESQUERDO, mantendo o motor DIREITO no sentido a frente (Forward): o robô irá girar sobre seu eixo para a esquerda.

Implementemos o caso 2 acima:

void leftMotor(void)   
{
  digitalWrite(eneLeftMotor,HIGH);
  digitalWrite(eneRightMotor,HIGH); 
  
  digitalWrite(leftMotor1,LOW);
  digitalWrite(leftMotor2,HIGH);
  digitalWrite(rightMotor1,HIGH);
  digitalWrite(rightMotor2,LOW);
}

Os demais comandos seguirão a mesma lógica, como ilustra a tabela abiaxo:

Moving the Robot Around

4: Completando o HW

Completing the HW

Siga o diagrama acima e complete o HW de seu Robô.

Você poderá executar alguns testes simples para verificar que seu código está OK.  Para isto, introduziremos um “botão” para iniciar o seu robô. Vamos instalá-lo na porta D0 do NodeMCU como mostrado no diagrama elétrico anterior.

Você poderá utilizar o programa abaixo para testar os movimentos de seu robô:

// Set Motor Control Pins
int rightMotor2 = 13;    // D7 - right Motor -
int rightMotor1 = 15;    // D8 - right Motor +
int leftMotor2 = 0;    // D3 - left Motor - 
int leftMotor1 = 2;    // D4 - left Motor +
int eneLeftMotor = 12;  // D6 - enable Mortor Left
int eneRightMotor = 14; // D5 - enable Mortor Right

int buttonPin = 16; // D0

void setup()
{
  Serial.begin(115200);

  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(eneLeftMotor, OUTPUT); 
  pinMode(eneRightMotor, OUTPUT); 
  pinMode(leftMotor1, OUTPUT); 
  pinMode(leftMotor2, OUTPUT);  
  pinMode(rightMotor1, OUTPUT);  
  pinMode(rightMotor2, OUTPUT);  

  digitalWrite(eneLeftMotor,LOW);
  digitalWrite(eneRightMotor,LOW);
  digitalWrite(leftMotor1,LOW);
  digitalWrite(leftMotor2,LOW);
  digitalWrite(rightMotor1,LOW);
  digitalWrite(rightMotor2,LOW);
      
  while (digitalRead(buttonPin))  // Wait for button to be pressed to move on 
  {  
  }
}

void loop()
{
  forwardMotor();
  delay (5000);
  stopMotor();
  delay (200);
  leftMotor();
  delay (3000);
  stopMotor();
  delay (200);
  forwardMotor();
  delay (5000);
  stopMotor();
  delay (200);
  rightMotor();
  delay (3000);
  stopMotor();
  delay (200);
  reverseMotor();
  delay (5000);
  stopMotor();
  delay (200);
} 

/* command motor forward */
void forwardMotor(void)   
{
  digitalWrite(eneLeftMotor,HIGH);
  digitalWrite(eneRightMotor,HIGH);
    
  digitalWrite(leftMotor1,HIGH);
  digitalWrite(leftMotor2,LOW);
  digitalWrite(rightMotor1,HIGH);
  digitalWrite(rightMotor2,LOW);
}

/* command motor backward */
void reverseMotor(void)   
{
  digitalWrite(eneLeftMotor,HIGH);
  digitalWrite(eneRightMotor,HIGH);
  
  digitalWrite(leftMotor1,LOW);
  digitalWrite(leftMotor2,HIGH);
  digitalWrite(rightMotor1,LOW);
  digitalWrite(rightMotor2,HIGH);
}

/* command motor turn left */
void leftMotor(void)   
{
  digitalWrite(eneLeftMotor,HIGH);
  digitalWrite(eneRightMotor,HIGH); 
  
  digitalWrite(leftMotor1,LOW);
  digitalWrite(leftMotor2,HIGH);
  digitalWrite(rightMotor1,HIGH);
  digitalWrite(rightMotor2,LOW);
}

/* command motor turn right */
void rightMotor(void)   
{
  digitalWrite(eneLeftMotor,HIGH);
  digitalWrite(eneRightMotor,HIGH);
  
  digitalWrite(leftMotor1,HIGH);
  digitalWrite(leftMotor2,LOW);
  digitalWrite(rightMotor1,LOW);
  digitalWrite(rightMotor2,HIGH);
}

/* command motor stop */
void stopMotor(void)   
{
  digitalWrite(eneLeftMotor,LOW);
  digitalWrite(eneRightMotor,LOW);

  digitalWrite(leftMotor1,LOW);
  digitalWrite(leftMotor2,LOW);
  digitalWrite(rightMotor1,LOW);
  digitalWrite(rightMotor2,LOW);
}

Quando você pressionar o botão, o robô começará a fazer os movimentos definidos no loop (). Os movimentos continuarão até que você pressione “Reset” no NodeMCU. Pressionando o botão “verde” novamente, o ciclo se repetirá.

O código acima poderá ser baixado de meu GitHub:

WiFi_Robot_NodeMCU_Android_Voice_Motor_tests

5: Montando o corpo do robô

body Assembly

  1. Use o Kit: Chassis, 2 Rodas, 2 Motores DC, 1 roda solta (coaster)
  2. Solde 2 fios de 10 cm (Vermelho e Preto) em cada polo do motor
  3. Fixe os motores ao chassi como mostrado na foto acima
  4. Monte o coaster
  5. Conecte os fios do motor à eletrônica (L293D)
  6. Fixe a bateria de 9V ao chassi
  7. Fixe a bateria de 5V sob o chassi

O robô deverá ficar com essa cara:

Body Final

6: Conectando o NodeMCU ao seu WiFi local

Conectemos o NodeMCU ao WiFi local, verificando seu endereço IP. Para isso, podemos utilizar o programa abaixo:

#include 
WiFiClient client;
WiFiServer server(80);
const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";

void setup() 
{
  Serial.begin(115200);
  connectWiFi();
  server.begin();
}

void loop() 
{
}

/* connecting WiFi */
void connectWiFi()
{
  Serial.println("Connecting to WIFI");
  WiFi.begin(ssid, password);
  while ((!(WiFi.status() == WL_CONNECTED)))
  {
    delay(300);
    Serial.print("..");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("NodeMCU Local IP is : ");
  Serial.print((WiFi.localIP()));
}

No monitor serial voce poderá observar o endereço IP dinâmico  designado pelo Modem ao seu NodeMCU.

Connecting the NodeMCU to Local WiFi

Tome nota deste endereço de IP. Precisaremos dele para conectar o App Android.

O código acima poderá ser baixado de meu GitHub:

NodeMCU_Connection_Test_EXT

7: Completando o código fonte para o NodeMCU

Para que nosso robô se mova, o NodeMCU deverá receber comandos provenientes do dispositivo Android. Para tal, definamos uma variável para receber estes comandos:

String  command ="";

Por exemplo, se a aplicação Android enviar como um comando: “forward” (a frente), o robô deverá avançar, invocando-se a função forwardMotor(). Veja abaixo:

if (command == "forward")
{
  forwardMotor();
}

O mesmo conceito deverá ser aplicado a todo os demais comandos e funções associadas tal como vimos no item 4:

  1. STOP: Pare
  2. LEFT: Vire à esquerda
  3. RIGHT: Vire à direita
  4. REVERSE: Dê marcha à ré
  5. FORWARD: Vá para a frente

Baixe o código completo: WiFi_Robot_NodeMCU_Android_Voice_EXT de meu GitHub.

Entre com as credenciais de sua rede local:

const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";

Carregue o código em seu NodeMCU e pronto! Você poderá verificar no Monitor Serial se o programa está em execução. Deixe o programa em execução para podermos testar o o aplicativo a ser desenvolvido na próxima etapa.

8: A App Android : “Designer Tab”

The Android App:

Usaremos o MIT App Inventor para o desenvolvimento de nossa App Android.

Principais componentes da Screen 1 (veja a foto anterior):

  • User Interface:
    • Input of IP Address
      • TextBox named “IP_Address”
    • 5 Command Buttons:
      • forward
      • reverse
      • right
      • left
      • stop
    • Voice Input Button
      • Voice_Input
  • Non Visible Components:
    • Web1
    • SpeachRecognizer1
    • TextToSpeach1
  • Other:
    • Text Box:
      • Speach_To_Text
    • Label:
      • Comm_Status

                  Screenshot_2017-04-02-14-36-34

9: A App Android: Botões

The Android App: Buttons

Na Tab “Blocks”, deveremos criar 5 Botões, um para cada comando. Todos eles seguirão a estrutura dos blocos acima.

Estes blocos serão chamados quando o botão “forward” (“botão com a seta para cima”) é pressionado.

Quando você clicar no botão, 3 ações serão executadas:

  1. Um comando será enviado no formato: http: / ip_address * / forward
  2. Um “eco” no mesmo formato é esperado
  3. Uma “mensagem” audível será executada pela App: no caso: “forward”

* O IP_Address será a que você digitar no seu App. Por exemplo, se o IP address é 10.1.0.3, a mensagem completa seria: http: /10.0.1.3/forward

Você poderá utilizar qualquer mensagem, ou até mesmo deixar a mensagem vazia.

10: A App Android: Reconhecimento de voz

The Android App: Voice Recognition

Os blocos acima mostram o código de reconhecimento de voz para o nosso aplicativo.

Note que, para qualquer comando de voz inserido, o resultado será um comando em letras minúsculas. Isso facilitará a descodificação do comando pelo NodeMCU.

Por exemplo, se você deseja mover o robô para a frente, uma palavra ou sentença deverá ser enviada para ser interpretada pelo NodeMCU. No exemplo abaixo, o código reconheceria qualquer uma das palavras: “forward”, “frente” ou “a frente “.

if (command == "forward" || command == "frente" || command == "a frente")  
{
  forwardMotor();
}

Assim, por exemplo quando digo “frente”, a App enviará : http: / 10.0.1.10/frente e o NodeMCU tomará o que é recebido após o “/”,  a palavra “frente” que será interpretada como um comando do tipo “forward”. Com este comando, a função forwardMotor () será invocada.

11: A App Android: Manipulação de erros

The Android App: Error Manipulation

Se ocorrer um erro, por exemplo, quando você diz um comando de voz não reconhecido pelo NodeMCU, o bloco acima irá gravar os detalhes do erro na última linha (Comm_Status) do App, conforme mostrado abaixo:

Screenshot_2017-04-02-14-36-50

12: Teste final

Final Test

Você poderá criar seu aplicativo passo a passo, como mostrado nas etapas anteriores ou fazer o upload do meu projeto completo (.aia) no MIT App Inventor, modificando-o de acordo a suas necessidades. Além disso, caso você não tenha experiência no desenvolvimento de aplicativos para Android, poderá executar o arquivo .apk diretamente em seu dispositivo Android.

Ambos, os arquivos .aia e .apk podem ser baixados de meu GitHub:

WiFi_Voice_Robot_Ctrl_V2.aia

WiFi_Voice_Robot_Ctrl_V2.apk

O video abaixo mostra alguns testes de motores utilizando-se do App:

Conclusão

Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica, robótica e do IoT!

Verifique o depositário no GitHub para obter os arquivos atualizados:

WiFi-Voice-Controlled-Robot

Saludos desde el sur del mundo!

Até o próximo tutorial!

Obrigado

Marcelo

Controle ativado por voz com Android e NodeMCU

Em meu último tutorial: Quando o IoT encontra a Inteligência Artificial: Automação residencial com Alexa e NodeMCU exploramos como equipamentos ativados por voz como o Amazon Echo-Dot utilizando-se de um serviço da web (como o “Alexa”) podem controlar “dispositivos inteligentes” em nossas casas. Neste novo tutorial faremos o mesmo,  porém  em vez de usar o Alexa desenvolveremos nossa própria App em um smartphone Android controlando, tanto com botões quanto por voz, nossos dispositivos domésticos.

O diagrama de blocos nos dá uma geral do que pretendemos desenvolver:

Block Diagram.jpg

e o filme nos mostra como ficará o projeto final:

1: Lista de materiais (BoM)

Valores em USD, utilizados apenas como referência

  1. NodeMCU ESP8266-12E ($8.79)
  2. Mini BreadBoard ($1.00)
  3. 400-point Experiment Breadboard Breadboard ($ 4.97)
  4. 4-Channel Relay Module ($8.49)
  5. LEDs (vermelho, amarelo, verde e azul) ($1.00)
  6. 4 x Resistor (220 ohm)
  7. Male-Female Dupont Cables ($1.00)
  8. Fonte externa DC de 5V ou bateria

….. e naturalmente um telefone ou tablet Android (qualquer modelo com wifi servirá).

2: Conectando o NodeMCU à rede local de WiFi

Conectaremos o NodeMCU a rede WiFi local,  verificando seu endereço IP. Para isso, usaremos o pequeno programa abaixo, o qual fará parte do projeto final:
#include <ESP8266WiFi.h>
WiFiClient client;
WiFiServer server(80);
const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";

void setup() 
{
  Serial.begin(115200);
  connectWiFi();
  server.begin();
}

void loop() 
{
}

/* connecting WiFi */
void connectWiFi()
{
  Serial.println("Connecting to WIFI");
  WiFi.begin(ssid, password);
  while ((!(WiFi.status() == WL_CONNECTED)))
  {
    delay(300);
    Serial.print("..");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("NodeMCU Local IP is : ");
  Serial.print((WiFi.localIP()));
}

No monitor serial voce poderá ver o IP Address assignado por seu Modem ao NodeMCU:

Serial Monitor Comm Test

Tome nota do endereço (em meu acaso: 10.0.1.3). Necessitaremos deste endereço para a conexão ao aplicativo Android que será desenvolvido mais adiante.

3: Montando o HW

Assembling the HW

Usaremos um módulo de relé de 4 canais para controlar 4 LEDs, simulando 4 dispositivos domésticos. Siga as instruções a seguir e termine as conexões:

Conecte as entradas dos relés com os pinos do NodeMCU como mostrado no diagrama e definido no código como mostrado abaixo:

int relay1 = 14;
int relay2 = 15;
int relay3 = 3;
int relay4 = 1;

Nossos dispositivos inteligentes serão simulados pelos LEDs coloridos:

  • relé 1 ==> LED vermelho
  • relé 2 ==> LED amarelo
  • relé 3 ==> LED verde
  • relé 4 ==> LED azul

Nosso Android App irá enviar um comando em forma de string,  o qual deverá ser interpretado pelo código de maneira a ativar cada um dos relés. Definamos as strings para cada comando:

  • Relé 1:
    • Ligar: “r1on”;
    • Desligar: “r1off”;
  • Relé 2:
    • Ligar: “r2on”;
    • Desligar: “r2off”;
  • Relé 3:
    • Ligar: “r3on”;
    • Desligar: “r3off”;
  • Relé 4:
    • Ligar: “r4on”;
    • Desligar: “r4off”;

Definamos uma variável que irá receber os comandos (command) e a lógica associada a mesma:

String  command ="";

Assim, por exemplo, se o aplicativo Android enviar como um comando: “r1on”,  o relé 1 (relay1) deverá ser ativado:

if (command == "r1on")
{
  digitalWrite(relay1, LOW);
}

Observe que os relés usados no projeto são ativados com um nível baixo (LOW).

Utilizando alsoif, escreveremos os demais comandos (veja o codigo completo ao final).

Também definiremos “comandos de grupo” para ligar (“allon”) e desligar (“alloff”) simultaneamente todos os dispositivos. Por exemplo, para ativar ao mesmo tempo todos os relés, usaremos o comando “allon” como mostrado abaixo:

    if (command == "allon") 
    {
      digitalWrite(relay1,LOW);
      digitalWrite(relay2,LOW);
      digitalWrite(relay3,LOW);
      digitalWrite(relay4,LOW);
    }

A mesma lógica deverá ser empregada para o comando “alloff”.

Siga o diagrama elétrico acima para concluir a conexão de todo o HW.

Agora faça o download do código completo:

Home_Automation_NodeMCU_Android_Voice_V2_EXT.ino a partir de meu GitHub.

Entre com as credenciais de sua rede local de WiFi:

const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";

Faça o upload do código em seu NodeMCU e pronto! Você poderá verificar no  Monitor Serial se o programa está em execução. Deixe o programa rodando para que se possa testar o aplicativo Android desenvolvido a partir do próximo passo.

CUIDADO: Quando fizer o upload do código, desligue a alimentação dos relés para não sobrecarregar o NodeMCU.

4: A App Android : “Designer Tab”

 Usaremos a aplicação on-line: MIT App Inventor para o desenvolvimento de nossaApp Android:

MIT V2 0

Componentes Principais da Screen1 (veja foto acima)

  • Entrada do endereço IP
    • TextBox denominado “IP_Address”
  • 8 botões ON / OFF, um para cada relé:
    • Relay_1_ON
    • Relay_2_OFF
    • Etc
  • 2 botões ON / OFF para todos os dispositivos:
    • All_Devices_ON
    • All_Devices_OFF
  • Botão de Entrada de Voz
    • Voice_Input
  • Componentes não visíveis:
    • Web1
    • SpeachRecognizer1
    • TextToSpeach1
  • Outros:
    • Caixa de texto:
      • Speach_To_Text
    • Label:
      • Comm_Status

Ao final o aplicativo deverá ficar assim:

Screenshot_2017-03-29-16-33-37

5: A App Android: Botões

Devemos criar na tab Blocks, 10 botões. Todos seguirão a mesma estrutura que os 2 mostrados na foto.

MIT V2 2

Esses blocos de 2 botões foram criados para:

  • Relay_1_ON. Click
  • Relay_1_OFF.Click

Estas funções são chamadas quando se “clica” em um desses botões. Por exemplo, quando você clica no botão Relay_1_ON, 3 ações serão executadas:

  1. Um comando será enviado no formato: http: / ip_address * / r1on
  2. Um “eco” no mesmo formato é esperado devido a “call Web1.Get”
  3. Uma “mensagem” sonora será lida pela App: no caso: “Relé 1 ligado”

* O IP_Address será o que você digitar na Tela 1. Utilizando-se o default (10.1.0.3), a mensagem real seria: http: /10.0.1.3/r1on

Voce poderá utilizar qualquer mensagem nesta etapa, ou deixá-la vazia (“”) caso não deseje um retorno auditivo.

6: O App Android: Reconhecimento de voz

Os blocos abaixo mostram a construção do código para o reconhecimento de voz de nosso aplicativo:

MIT V2 3

Note que para qualquer comando de voz, o comando enviado será sempre em  minúsculas (uso do bloco de texto downcase). Isso facilitará a decodificação do comando de voz pelo NodeMCU.

Por exemplo, se você deseja “ativar” o relé 1, uma palavra ou sentença deve ser enviada para ser reconhecida pelo código do NodeMCU. Enviaremos para isto um comando de voz em português: “Ligar UM”

if (command == "r1on"  || command == "ligar 1"    || command == "ligar um")
{
  digitalWrite(relay1,LOW);
}

Assim, quando digo “ligar um”, a App irá enviar: http: / 10.0.1.3/ligar um (ou http: / 10.0.1.3/ligar 1) e o NodeMCU colocará seu pino em LOW,  ativando o relé 1.

7: O App Android: Manipulação de erro

The Android App: Error Manipulation

Se ocorrer um erro, o bloco acima escreverá os detalhes referente ao mesmo na última linha do App (Comm_Status). Você somente irá ver-lo se ao criar o App usar a opção Responsive.

8: Testes finais

Final Test

Você poderá criar seu aplicativo passo a passo, como mostrado nas etapas anteriores ou utilizar o fonte de meu projeto (.aia) diretamente no MIT App Inventor:

MIT V2 1

Caso você não tenha experiência no desenvolvimento de aplicativos Android, poderá executar o arquivo .apk diretamente em seu dispositivo Android.

Ambos arquivos .aia e .apk poderão ser baixados de meu GitHub:

Home_Relay_Voice_Ctrl_V2.aia

Home_Relay_Voice_Ctrl_V2.apk

9: Conclusão

Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica, robótica e do IoT!

Verifique o depositário no GitHub para obter os arquivos atualizados:

Home-Automation-with-Android-and-NodeMCU

Saludos desde el sur del mundo!

Até o próximo tutorial!

Obrigado

Marcelo

MJRobot é novamente finalista em concurso no site do Instructables.com!!!!!!

Com apenas 1 semana de vida e 25.000 views no site do Instructables.com, meu projeto: IoT feito simples: Estação meteorológica doméstica com NodeMCU e OLED acaba de ser eleito um dos finalistas do concurso: “SENSORS”.

Sensors finalist 2

Muito obrigado a todos que prestigiaram o projeto lá no site! Isso me deixa muito orgulho e animado a continuar nessa aventura pelos caminhos da eletrônica, IoT e robótica!

Nos vemos em meu próximo post!

Saludos desde el sur del mundo!

Abração

Marcelo