<

Exibir mensagens

Esta seção lhe permite ver todas as mensagens deste membro. Note que você só pode ver as mensagens das áreas às quais você tem acesso.


Tópicos - Boss

Páginas: [1] 2 3 ... 5
1
O Google lançou jogo que ensina a lógica de programação a crianças e adultos

Hoje na página sua página principal, o Google lançou jogo que ensina lógica de programação para crianças. O programa é uma adaptação do logotipo do site de buscas – modificações que são conhecidas como “doodles” – e comemora os 50 anos da criação de linguagens de computação orientada para os mais pequenos. Introduzindo desta forma simples e divertida, toda a lógica da programação nas suas diversas linguagens.

O objetivo do jogo é fazer com que um coelho apanhe cenouras que estão espalhadas pela tela, para passar de nível. Para isso, é preciso programar qual o caminho o bichinho fará. Isso é feito organizando uma sequência de setas e outros comandos na tela. Quando se clica em “play”, o coelho vai saltando nas direções indicadas previamente.

Dentre as linguagens de programação voltadas para crianças estão o Logo, criado em 1967, e o Scratch. O objetivo desse tipo de código é ensinar a lógica usada para fazer aplicações para computador.

Atualmente já existem kits de robótica orientados para educação em que crianças e adultos podem utilizar esta “linguagem de programação por blocos” para colocar o robot a funcionar, um carrinho a desviar-se dos obstáculos e até controlado por Smartphone. Podem saber mais sobre estes Kits Educativos no site da ElectroFun, sendo uma otima alternativa para as crianças neste Natal! Além de divertido ajuda desde novos a desenvolverem as suas capacidades de raciocino e lógica para vencer desafios.

Pode para já praticar no Google montar bloco-a-bloco até o coelhinho chegar ao seu objetivo! Jogue aqui!


2
Projetos / Como Controlar a sua Casa pelo Smartphone? (Sem programação)
« Online: Dezembro 08, 2017, 09:27:54 am »
Como Controlar a sua Casa pelo Smartphone? (Sem programação)



Olá a todos, hoje vamos ver como controlar a nossa casa, os nossos eletrodomésticos, luzes, portas, etc pelo Smartphone. Mas desta vez otimo para quem não sabe programar Arduino.


Vamos utilizar um produto da Sonoff que podem comprar na ElectroFun:


https://www.electrofun.pt/iot-e-domotica/sonoff-4ch-4-canais-interruptor-wifi


 



 


Como podem ver tem possibilidade de ligar de forma independente 4 canais distintos.


Após instalar a respetiva aplicação, poderão em tempo real, em, qualquer parte do mundo, controlar individualmente cada canal. E ainda se desejar programar um horário especifico de funcionamento, ideal para iluminação de jardim, sistemas de rega, etc.


Outros produtos interessantes da Sonoff AQUI.



3
Projetos / Como criar um Radar com o Arduino? [Video]
« Online: Dezembro 08, 2017, 09:27:48 am »
Como criar um Radar com o Arduino? [Video]



Hoje vamos ver como podemos criar um fantástico Radar como nos filmes!


O nosso componentes principal que nos vai permitir criar um radar será o Sensor de Distância Ultrasónico HC-SR04.


Desta vez para criarmos o intarface animado em tempo real, vamos utilizar uma ferramenta nova o Processing. Podem fazer download e saber mais informações no site oficial: www.processing.org 


 


Mais uma vez vamos explicar como fazer este projeto. Abaixo poderão encontrar a lista de materiais utilizados, esquema de montagem e o código para o Arduino.


 



 


 


# Esquema de montagem:



 


 


 


# Código Utilizado no Arduino IDE:


#include <Servo.h>.
// Defines Tirg and Echo pins of the Ultrasonic Sensor
const int trigPin = 10;
const int echoPin = 11;
// Variables for the duration and the distance
long duration;
int distance;
Servo myServo; // Creates a servo object for controlling the servo motor
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600);
myServo.attach(12); // Defines on which pin is the servo motor attached
}
void loop() {
// rotates the servo motor from 15 to 165 degrees
for(int i=0;i<=180;i++){
myServo.write(i);
delay(30);
distance = calculateDistance();// Calls a function for calculating the distance measured by the Ultrasonic sensor for each degree

Serial.print(i); // Sends the current degree into the Serial Port
Serial.print(","); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
Serial.print(distance); // Sends the distance value into the Serial Port
Serial.print("."); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
}
// Repeats the previous lines from 165 to 15 degrees
for(int i=180;i>0;i--){
myServo.write(i);
delay(30);
distance = calculateDistance();
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
}
}
// Function for calculating the distance measured by the Ultrasonic sensor
int calculateDistance(){

digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds
distance= duration*0.034/2;
return distance;
}

 


 


# Código Utilizado no PROCESSING:


import processing.serial.*; // Importa as bibliotecas para comunicação de Seriew
import java.awt.event.KeyEvent; // Importa as bibliotecas para ler a informação da entrada de serie
import java.io.IOException;
Serial myPort; // define o objeto Serial
// define as variaveis
String angle="";
String distance="";
String data="";
String noObject;
float pixsDistance;
int iAngle, iDistance;
int index1=0;
int index2=0;
PFont orcFont;
void setup() {

size (1280, 720); // **Mudar isto para a sua resolução**
smooth();
myPort = new Serial(this,"COM3", 9600); // Começa a comunicação Serie
myPort.bufferUntil("."); // Lê o Serial Monitor até ao ponto final
orcFont = loadFont("OCRAExtended-30.vlw");
}
void draw() {

fill(98,245,31);
textFont(orcFont);
// Simula o movimento das linhas
noStroke();
fill(0,4);
rect(0, 0, width, height-height*0.065);

fill(98,245,31); // green color
// Chama as funções Radar, line, Object, Text
drawRadar();
drawLine();
drawObject();
drawText();
}
void serialEvent (Serial myPort) { // Começa a ler a informação de Serie
// lê a informação de Serie até ao caracter ".", esta informação é atribuida a uma string chamada "data".
data = myPort.readStringUntil(".");
data = data.substring(0,data.length()-1);

index1 = data.indexOf(","); //
angle= data.substring(0, index1);
distance= data.substring(index1+1, data.length());

// Converte as variaveis string em Integer
iAngle = int(angle);
iDistance = int(distance);
}
void drawRadar() {
pushMatrix();
translate(width/2,height-height*0.074); // Move as coordenadas iniciais para outro local
noFill();
strokeWeight(2);
stroke(98,245,31);
// Desenha os semicirculos
arc(0,0,(width-width*0.0625),(width-width*0.0625),PI,TWO_PI);
arc(0,0,(width-width*0.27),(width-width*0.27),PI,TWO_PI);
arc(0,0,(width-width*0.479),(width-width*0.479),PI,TWO_PI);
arc(0,0,(width-width*0.687),(width-width*0.687),PI,TWO_PI);
// Desenha as linhas dos angulos
line(-width/2,0,width/2,0);
line(0,0,(-width/2)*cos(radians(30)),(-width/2)*sin(radians(30)));
line(0,0,(-width/2)*cos(radians(60)),(-width/2)*sin(radians(60)));
line(0,0,(-width/2)*cos(radians(90)),(-width/2)*sin(radians(90)));
line(0,0,(-width/2)*cos(radians(120)),(-width/2)*sin(radians(120)));
line(0,0,(-width/2)*cos(radians(150)),(-width/2)*sin(radians(150)));
line((-width/2)*cos(radians(30)),0,width/2,0);
popMatrix();
}
void drawObject() {
pushMatrix();
translate(width/2,height-height*0.074); // Move as coordenadas iniciais para outro local
strokeWeight(9);
stroke(255,10,10); // red color
pixsDistance = iDistance*((height-height*0.1666)*0.025); // cobre a distancia entre o sensor e o objeto
// limiting the range to 40 cms
if(iDistance<40){
// Desenha o objeto de acordo com a distancia e o angulo
line(pixsDistance*cos(radians(iAngle)),-pixsDistance*sin(radians(iAngle)),(width-width*0.505)*cos(radians(iAngle)),-(width-width*0.505)*sin(radians(iAngle)));
}
popMatrix();
}
void drawLine() {
pushMatrix();
strokeWeight(9);
stroke(30,250,60);
translate(width/2,height-height*0.074); // Move as coordenadas iniciais para outro local
line(0,0,(height-height*0.12)*cos(radians(iAngle)),-(height-height*0.12)*sin(radians(iAngle))); // Desenha a linha de acordo com o angulo
popMatrix();
}
void drawText() { // Escreve o texto no ecra

pushMatrix();
if(iDistance>40) {
noObject = "Out of Range";
}
else {
noObject = "In Range";
}
fill(0,0,0);
noStroke();
rect(0, height-height*0.0648, width, height);
fill(98,245,31);
textSize(25);

text("10cm",width-width*0.3854,height-height*0.0833);
text("20cm",width-width*0.281,height-height*0.0833);
text("30cm",width-width*0.177,height-height*0.0833);
text("40cm",width-width*0.0729,height-height*0.0833);
textSize(40);
text("Object: " + noObject, width-width*0.875, height-height*0.0277);
text("Angle: " + iAngle +" °", width-width*0.48, height-height*0.0277);
text("Distance: ", width-width*0.26, height-height*0.0277);
if(iDistance<40) {
text("        " + iDistance +" cm", width-width*0.225, height-height*0.0277);
}
textSize(25);
fill(98,245,60);
translate((width-width*0.4994)+width/2*cos(radians(30)),(height-height*0.0907)-width/2*sin(radians(30)));
rotate(-radians(-60));
text("30°",0,0);
resetMatrix();
translate((width-width*0.503)+width/2*cos(radians(60)),(height-height*0.0888)-width/2*sin(radians(60)));
rotate(-radians(-30));
text("60°",0,0);
resetMatrix();
translate((width-width*0.507)+width/2*cos(radians(90)),(height-height*0.0833)-width/2*sin(radians(90)));
rotate(radians(0));
text("90°",0,0);
resetMatrix();
translate(width-width*0.513+width/2*cos(radians(120)),(height-height*0.07129)-width/2*sin(radians(120)));
rotate(radians(-30));
text("120°",0,0);
resetMatrix();
translate((width-width*0.5104)+width/2*cos(radians(150)),(height-height*0.0574)-width/2*sin(radians(150)));
rotate(radians(-60));
text("150°",0,0);
popMatrix();
}

 


# Lista de Material:




4
Como ligar um Relógio RTC e Sensor de Temperatura num Display OLED [Video]



Hoje desenvolvemos um mini projeto que responde às seguintes questões:


– Como ligar um Relogio Digital em Tempo real (RTC) ao Arduino?

– Como ligar um display colorido OLED ao Arduino?

– Como ligar um sensor de temperatura e humidade DHT11 ao Arduino?


Passo-a-passo vamos entao de seguida ver como fazer este projeto que responderá a estas perguntas. Abaixo poderão encontrar a lista de materiais utilizados, esquema de montagem e o código para o Arduino.


 



 


# Esquema de montagem:



 


# Livrarias Necessárias:


Poderá fazer download das livrarias necessária a este projetos nos links abaixo.


DS3231.h


dht.h


Adafruit_GFX.h


Adafruit_SSD1306.h


As restantes já vem na aplicação Arduino IDE.


 


# Código Utilizado:


 


#include <DS3231.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <dht.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

 

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

DS3231 rtc(SDA, SCL);
dht DHT;
#define DHT11_PIN 7

void setup() {

rtc.begin();

display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
display.clearDisplay();
display.display();
delay(50);

}

 

void loop() {
int chk = DHT.read11(DHT11_PIN);

display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(1,0);
display.print(" ");
display.println(rtc.getTimeStr());

display.setTextSize(1);
display.setTextColor(WHITE);
display.print(" ");
display.print("Temp");
display.print(" ");
display.println("Humidade");

display.print(DHT.temperature);
display.print(" C");
display.print(" ");
display.print(DHT.humidity);
display.println(" %");
display.display();
delay(1000);
display.clearDisplay();

}

 


# Lista de Material:




5
Projetos / Controle ativado por voz com Android e NodeMCU
« Online: Dezembro 08, 2017, 09:26:54 am »
Controle ativado por voz com Android e NodeMCU



O diagrama de blocos sumariza o que pretendemos desenvolver:


Block Diagram.jpg


e o vídeo mostra como vai ficar o projeto final:




1: Lista de materiais (BoM)




  1. NodeMCU ESP8266-12E

  2. Mini BreadBoard

  3. 400-point Experiment Breadboard Breadboard

  4. 4-Channel Relay Module

  5. LEDs (vermelho, amarelo, verde e azul)

  6. 4 x Resistor (220 ohm)

  7. Male-Female Dupont Cables

  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
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). Somente irá ver-lo se ao criar o App usar a opção Responsive.





8: Testes finais


Final Test


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 não tenha experiência no desenvolvimento de aplicativos Android, poderá executar o arquivo .apk diretamente no seu dispositivo Android.


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


Home_Relay_Voice_Ctrl_V2.aia


Home_Relay_Voice_Ctrl_V2.apk




6
Quando o IoT encontra a Inteligência Artificial: Automação residencial com Alexa e NodeMCU



Neste tutorial, vamos explorar como usar a Alexa, um assistente pessoal inteligente desenvolvido pela Amazon Lab126, popularizado pelo Amazon Echo e Echo-Dot.


Alexa é capaz de interação de voz, reprodução de música, fazer listas de tarefas, configurar alarmes, transmitir podcasts, tocar audiobooks e fornecer informações meteorológicas, de trânsito e outras informações em tempo real. Alexa também pode controlar vários dispositivos inteligentes usando-se como um hub de automação residencial. Vamos usar neste projeto, o “Echo-Dot”, que permite aos usuários ativar o dispositivo usando um wake-word (no caso, “Alexa”).


echo-dot features


No espaço da Domótica (automação residencial), Alexa pode interagir com vários dispositivos diferentes como Philips Hue, Belkin Wemo, SmartThings, etc. Em nosso caso, emularemos dispositivos do tipo WeMo, como estes mostrados abaixo (mas por apenas uma fração de seu preço):


WeMo


WeMo é uma série de produtos da Belkin International, Inc. que permitem aos usuários controlar eletrônicos domésticos de qualquer lugar. A suite de produtos inclui um interruptor, sensor de movimento, Insight Switch, interruptor de luz, câmera e app. O WeMo Switch (nosso caso aqui) pode ser conectado a qualquer tomada de casa, que pode ser controlada a partir de um iOS ou Android smartphone executando o WeMo App, via rede doméstica WiFi ou rede de telefonia móvel.


O diagrama abaixo mostra o que será desenvolvido em nosso projeto:


Home Automation Block Diagram V2


E o vídeo abaixo, mostra como ficará o projeto ao final:



1: Lista de materiais (BoM)



  • NodeMCU ESP8266-12E



  • Echo Dot (2nd Generation) – Black



  • Mini BreadBoard



  • 400-point Experiment Breadboard Breadboard



  • 4-Channel Relay Module



  • LEDs (vermelho e verde)



  • 2 x Resistor (220 ohm)



  • 5V 2 Terminals Electronic Continuous Sound Buzzer



  • Male-Female Dupont Cables



  • DC 5V 0.2A Cooling Fan



  • Fonte de alimentação externa de 5V DC ou batteria


2: Emulando o WeMo Switch


wemo_echo_upnp


Os dispositivos WeMo utilizam UPnP para executar certas funções através da rede. A função de detecção do dispositivo começa com o Echo ou Echo-Dot (em nosso caso aqui) à procura de dispositivos WeMo utilizando UPnP. O dispositivo então responde ao Echo-Dot com seu URL utilizando HTTP sobre UDP. OEcho-Dot então solicita a descrição do dispositivo utilizando esse URL HTTP. A descrição é então retornada como uma resposta HTTP. Neste ponto, o Echo-Dot já “descobriu” o dispositivo. O Echo-Dot simplesmente se conectará ao WeMo através da interface HTTP e emitirá um comando do tipo “SetBinaryState”. O WeMo então “obedecerá”, retornando uma confirmação via HTTP. O diagrama  acima resume a comunicação entre o Echo-Dote o WeMo Switch.


Este tutorial não entrará em muito mais detalhes sobre este tópico. Procurei compilar informações obtidas em vários projetos da web, simplificando sua apresentação de maneira a apresentar uma visão geral sobre o uso da Alexa na automação residencial .


Algumas excelentes fontes de informação sobre o assunto poderão ser encontradas nos links abaixo:


HOW TO MAKE AMAZON ECHO CONTROL FAKE WEMO DEVICES, escrito por Rick Osgut


Building an IoT power switch with the ESP8266 (and control it with your Amazon Echo!)  escrito por  Wai Lun


Amazon Alexa + WeMos switch made with Arduino D1 Mini , codigos desenvolvidos por Aruna Tennakoon:


Projects using NodeMCU, conjunto de códigos desenvolvidos por Christopher Kuzma


Dito isto, com o que fui aprendendo nos diversos sites acima terminei chegando a um código de teste, o qual você poderá baixar desde meu GitHib: Alexa_LED_Control_V2_EXT.ino


Verifique se possui todas as bibliotecas necessárias para executar o código, como: ESP8266WiFi.h, ESP8266WebServer.h e WiFiUdp.h. Caso não as tenha, você poderá obtê-las aqui:  Arduino core for ESP8266 WiFi chip.


3: Criando nosso WeMo Switch com o NodeMCU


Alex and NodeMCU


Para o nosso primeiro teste, conectemos um LED ao NodeMCU pino D1 como mostrado no diagrama abaixo:


NodeMCU and LED


Abra o arquivo  Alexa_LED_Control_V2_EXT.ino , o qual você baixou de meu GitHub e entre com suas credenciais de rede:


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

Confirme se você definiu corretamente o pino onde o LED está conectado e dê um nome ao seu dispositivo. Alexa reconhecerá seu dispositivo por este nome:


 
String device_name = "lights";  // Name of device
int relayPin = D1;              // Pin to toggle
 

No meu caso, o dispositivo será denominado “lights“. Aqui neste primeiro exemplo o dispositivo acionará um único LED, mas o NodeMCU poderia estar conectado a um relé que por sua vez poderia ligar as luzes de meu laboratório, por exemplo.


Carregue o código no NodeMCU.


No monitor serial você pode ver a mensagem “Connecting to UDP” e “Connection Successful”. Isso significa que do lado NodeMCU tudo está OK.


 


Serial Monitor1


Estou a levar em consideração que já tenha o Echo-Dot instalado em sua rede., bem como o Alexa App no seu smartphone. Os procedimentos para a instalação de ambos é bem simples e basta seguir as instruções da Amazon fornecidas junto com o dispositivo.


Agora, necessitamos que a Alexa encontre seu dispositivo. Existem dois métodos para isso:



  • Utilizando o aplicativo Alexa no smartphone como mostrado nas fotos abaixo. Em nosso caso, a Alexa encontrará “1 Smart Home device”:  lights WeMo Switch.

  • Alexa app

  • Pedindo diretamente à Alexa através de um comando de voz, como por exemplo: “Alexa, Find connected devices” como poderá ser visto no vídeo abaixo:


  • Uma vez que a Alexa descobriu seu dispositivo, você poderá usar comandos de voz para o acionamento do dispositivo como mostrado abaixo:



  • 4: Acionando vários dispositivos ao mesmo tempo



  • IMG_1224




  • Aprofundando um pouco mais,  desenvolveremos um sistema um pouco mais realista que acionará vários dispositivos ao mesmo tempo. Desta maneira, o projeto poderia ser usado em projetos envolvendo automação residencial  (domótica).



    Usaremos um módulo de relé de 4 canais para controlar 2 lâmpadas e 2 tomadas.


    Esta parte do projeto foi baseada em grande parte no tutorial de Charles Gantt,


    How To: DIY Home Automation With NodeMCU and Amazon Alexa.


    Siga as instruções abaixo:


    Conecte as entradas dos relés com os pinos do NodeMCU conforme descrito abaixo:




 
int relayOne = 14;  // NodeMCU pin D5
int relayTwo = 15;  // NodeMCU pin D8
int relayThree = 3; // NodeMCU pin RX
int relayFour = 1;  // NodeMCU pin TX
 

Nossos “smart devices” serão 2 lâmpadas fixas (“Lights”)e 2 tomadas para uso geral (“Outlets”). Como vimos nas etapas anteriores, deveremos emular “WeMo Devices” e para fazer isso devemos nomeá-los como abaixo:



  • Light One



  • Light Two



  • Outlet One



  • Outlet Two


Em seguida, deveremos defini-los em nosso código para que a Alexa consiga encontrá-los. Também definiremos 2 comandos (on e off) e um número de porta de comunicação (“Port”) para cada dispositivo.


O formato geral deve ser:


 
lightOne = new Switch("Light One", 80, lightOneOn, lightOneOff);
lightTwo = new Switch("Light Two", 81, lightTwoOn, lightTwoOff);
outletOne = new Switch("Outlet One", 82, outletOneOn, outletOneOff);
outletTwo = new Switch("Outlet Two", 83, outletTwoOn, outletTwoOff);
 

Agora, você deve definir as 2 funções relacionadas a cada condição do dispositivo:


Para as lâmpadas:


 
void lightOneOn() {
  Serial.print("Switch 1 turn on ...");
  digitalWrite(relayOne, LOW);   // sets relayOne on
}

void lightOneOff() {
  Serial.print("Switch 1 turn off ...");
  digitalWrite(relayOne, HIGH);   // sets relayOne off
}

void lightTwoOn() {
  Serial.print("Switch 2 turn on ...");
  digitalWrite(relayThree, LOW);   // sets relayTwo on
}

void lightTwoOff() {
  Serial.print("Switch 2 turn off ...");
  digitalWrite(relayThree, HIGH);   // sets relayTwo Off
}
 

E para as tomadas:


 
void outletOneOn() {
  Serial.print("Socket 1 turn on ...");
  digitalWrite(relayFour, LOW);   // sets relayThree on
}

void outletOneOff() {
  Serial.print("Socket 1 turn off ...");
  digitalWrite(relayFour, HIGH);   // sets relayThree off
}

void outletTwoOn() {
  Serial.print("Socket 2 turn on ...");
  digitalWrite(relayTwo, LOW);   // sets relayFour on
}

void outletTwoOff() {
  Serial.print("Socket 2 turn off ...");
  digitalWrite(relayTwo, HIGH);   // sets relayFour off
}
 

Uma vez que estamos utilizando relés, poderíamos testar o projeto com  qualquer tipo de dispositivo real como TVs, geladeiras, etc. Obviamente que pelas especificações dos relés utilizados neste projeto, os dispositivos estariam limitados a 250VAC/10A ou 30 VDA/30A.


Em meu caso, decidi testar os 4 WeMo switches com dispositivos alimentados externamente com 5 V DC .



  • Como “Light 1”,  usarei um LED vermelho



  • Como “Light 2”, usarei um LED verde



  • Como “Outlet 2”, usarei um pequeno buzzer (pense em um rádio, aparelho de som…)



  • Como “Outlet 1”, usarei um pequeno ventilador


Abaixo o diagrama elétrico com as conexões:


Home Automation Electric Diagram


Com o HW pronto, baixe o código de meu GitHub: NODEMCU_ALEXA_WeMos_4X_Serial_Monitor_EXT.ino


Entre com suas credenciais de rede:


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

E pronto!


Siga o mesmo procedimento como definido na etapa anterior para permitir que a Alexa encontre seus 4 dispositivos.


O vídeo abaixo mostra uma demonstração desta etapa:



5: Aplicação em Domótica (Automação Residencial)


Neste ponto do projeto, possuímos 4 dispositivos inteligentes funcionando adequadamente, os quais podem ser ativados e desativados individualmente. Mas suponha que queremos agrupá-los de maneira a serem utilizados em nossa casa. O que deveria ser feito?


Por exemplo, suponha que a nossa casa tenha 2 cômodos:



  • Quarto (“Bed Room”)



  • Sala (“Living Room”)


Agora, suponha que você queira ter uma lâmpada e uma tomada em cada habitação. O que devemos fazer, é agrupar nossos 4 dispositivos como mostrado no diagrama de blocos da introdução:



  • IMG_9708Quarto (Bed Room)

    • Light 2

    • Outlet 1 (Ventilador)



  • Sala (Living Room)

    • Light1

    • Outlet 2 (Buzzer)





Também criaremos outro grupo para lidar com todos os dispositivos, ativando / desativando todos os dispositivos ao mesmo tempo.


Criaremos uma versão 2 de nosso código onde teremos  3 novos “switches” que agora devem ser também  ser identificados pela Alexa. Para isto, adicionemos as seguintes linhas ao nosso código:


1. Definição das “Switches”:


 
Switch *allDevices = NULL;
Switch *bedRoom = NULL;
Switch *livingRoom = NULL;
 

2. Declaração dos “callbacks” para os novos grupos de dispositivos:


 
void allDevicesOn();
void allDevicesOff();
void bedRoomOn();
void bedRoomOff();
void livingRoomOn();
void livingRoomOff();
 


  1. No setup(), devemos associar os switches com os novos callbacks and Ports (Lembre-se que temos um máximo de 14 dispositivos que podem ser manipulados com este código):


 
allDevices = new Switch("All Devices", 84, allDevicesOn, allDevicesOff);
bedRoom = new Switch("Bed Room", 85, bedRoomOn, bedRoomOff);
livingRoom = new Switch("Living Room", 86, livingRoomOn, livingRoomOff);
 


  1. Adicionando “Switches upnp Broadcast Responder” ao setup():


 
upnpBroadcastResponder.addDevice(*allDevices);
upnpBroadcastResponder.addDevice(*bedRoom);
upnpBroadcastResponder.addDevice(*livingRoom);
 


  1. Adicionando as linhas ao loop():


 
allDevices->serverLoop();
bedRoom->serverLoop();
livingRoom->serverLoop();
 


  1. E finalmente, criemos as funções para os “grupos de dispositivos” com as ações a serem executadas quando a Alexa receber um comando de voz:


 
void allDevicesOn()
{
  Serial.print("All Devices turn on ...");
  digitalWrite(relayOne, LOW);   // sets relay1 on
  digitalWrite(relayTwo, LOW);   // sets relay2 on
  digitalWrite(relayThree, LOW);   // sets relay3 on
  digitalWrite(relayFour, LOW);   // sets relay4 on
}

void allDevicesOff()
{
  Serial.print("All Devices turn off ...");
  digitalWrite(relayOne, HIGH);   // sets relay1 off
  digitalWrite(relayTwo, HIGH);   // sets relay2 off
  digitalWrite(relayThree, HIGH);   // sets relay3 off
  digitalWrite(relayFour, HIGH);   // sets relay4 off
}

void bedRoomOn()
{
  Serial.print("Bed Room turn on ...");
  digitalWrite(relayThree, LOW);   // sets relay3 on
  digitalWrite(relayFour, LOW);   // sets relay4 on
}

void bedRoomOff()
{
  Serial.print("Bed Room turn off ...");
  digitalWrite(relayThree, HIGH);   // sets relay3 off
  digitalWrite(relayFour, HIGH);   // sets relay4 off
}

void livingRoomOn()
{
  Serial.print("Living Room turn on ...");
  digitalWrite(relayOne, LOW);   // sets relay1 on
  digitalWrite(relayTwo, LOW);   // sets relay2 on
}

void livingRoomOff()
{
  Serial.print("Living Room turn off ...");
  digitalWrite(relayOne, HIGH);   // sets relay1 off
  digitalWrite(relayTwo, HIGH);   // sets relay2 off
}
 

Este procedimento de 6 passos poderá ser utilizado para qualquer comando, dispositivo ou grupo de dispositivos que você deseja adicionar ao seu projeto.


Você poderá baixar o código completo desta etapa. desde meu GitHub:


NODEMCU_ALEXA_WeMos_4X_V2_EXT


Depois que o código é enviado e executado pelo NodeMCU, é hora de solicitar Alexa que “localize os novos dispositivos”. Como explicado anteriormente, você poderá fazê-lo usando um comando de voz ou pelo Alexa App. Em ambos casos, o resultado poderá ser verificado no aplicativo como mostrado abaixo. Sete dispositivos (“WeMo Switches”) deverão ser encontrados agora pela Alexa:



  • IMG_1261Living Room



  • Bed Room



  • All Devices



  • Outlet One



  • Outlet Two



  • Light One



  • Light Two



O vídeo abaixo mostra como nosso projeto completo de Automação Residencial funcionará:




7
“ArduFarmBot 2” – Sistema automático para irrigação e calor, agora com o NodeMCU e Blynk




 


Com base em dados recolhidos de uma plantação qualquer tais como, temperatura e humidade, tanto do ar quanto do solo, o ArduFarmBot 2 decidirá a quantidade certa (e quando) a planta deve receber calor e água. O sistema deverá também permitir a intervenção manual de um operador para controlar uma bomba de água e uma lâmpada elétrica para gerar calor para a plantação. Esta intervenção manual deverá ser possível de ser executada tanto no local como remotamente via Internet.


O sistema deverá receber como:


A- Entrada:


Sensores:



  • Temperatura do ar

  • Humidade Relativa ao Ar

  • Temperatura do solo

  • Humidade do solo


Botões:



  • Bomba ON / OFF

  • Lâmpada ON / OFF


B- Saída:


Atuadores:



  • Relé para controle da bomba

  • Relé para controle de lâmpada


Mensagens automáticas devem ser enviadas na ocorrência de eventos, tais como:



  • Bomba LIGADA

  • Lâmpada LIGADA

  • Sistema off-line


Exibição de dados



  • Todos os dados analógicos e digitais devem estar disponíveis para avaliação imediata


Armazenamento de dados



  • Dados históricos devem ser armazenados remotamente


O diagrama de blocos abaixo mostra os principais componentes do projeto.



 Lista de materiais:



 


O NodeMCU



O NodeMCU ESP-12E é a versão integrada do popular ESP8266, um Serial to Wi-Fi System On a Chip (SoC), que apareceu pela primeira vez em 2013 e lançado no mercado já no ano seguinte. O ESP8266 foi desenvolvido pela empresa chinesa com sede em Shangai, Espressif Systems, uma fabricante de circuitos integrados focada no desenvolvimento de chips de RF, particularmente Wi-Fi.


Existem vários módulos no mercado que se utilizam do chip ESP8266. Eles são nomeados ESP-NN, onde NN é um número 01, 02, … .. 12, etc. e as vezes seguido de uma letra. Estes módulos tipicamente possuem: o ESP8266 SoC, memória flash, um cristal e na maioria dos casos, uma antena. No link poderá encontrar a lista completa de dispositivos baseados no ESP8266 encontradas no mercado: Família ESP8266.


Os 2 módulos mais importantes são sem dúvida, a ESP-01 e o ESP-12E. No ArduFarmBot 2, usaremos o: ESP-12E Development Board (NodeMCU DevKit 1.0)


Para aumentar ainda mais a capacidade de utilização do módulo ESP-12E, foram adicionados regulação de potência e conectividade USB. O ESP-12E inclui:



  • Adaptador USB para UART: Silicon Labs CP2102.

  • NCP1117 3,3VDC Voltage Regulator.

  • Conector micro-USB.

  • Pinos adicionais com GND, Vin, 3,3VDC para facilitar o acesso durante o desenvolvimento.


O NodeMCU ESP-12E é um dispositivo pronto para ser usado, basta que instale os drivers USB no seu computador e comece a escrever programas que se conectam à sua rede Wi-Fi.



  • Suporte STA / AP / STA + AP 3 modos de funcionamento;

  • Pilha de protocolo TCP / IP embutida, suporte a conexão de cliente TCP de múltiplos canais (máximo 5);

  • 0 ~ D8, SD1 ~ SD3: usado para GPIO, PWM (D1-D8), IIC, ect; A capacidade dirigida pode ser alcançada em 15mA;

  • AD0: ADC de 10 bits de sentido único;

  • Entrada de energia: 4.5V ~ 9V (10VMAX), suporta USB alimentado e USB debug;

  • Corrente de trabalho: ≈ 70mA (200mA MAX, continuar), em espera <200uA;

  • Taxa de dados de transmissão: 110-460800bps;

  • Suporta interface de comunicação de dados UART / GPIO;

  • Apoie o firmware de atualização remotamente (OTA);

  • Suporte Smart Link;

  • Temperatura de trabalho: -40 ℃ ~ + 125 ℃;

  • Modo Driven: ponteira H de grande potência

  • Peso: 7g.


Instalando o NodeMCU com o Arduino IDE


Se já tiver o NodeMCU instalado com o IDE, ignore esta etapa!


Se deseja programar e usar o NodeMCU como se fosse um Arduino, a boa notícia é que é possível escrever-se firmwares personalizados e carregá-los no chip (“flash-it”). É importante lembrar que qualquer novo “firmware personalizado” irá substituir qualquer coisa previamente armazenada na memória flash do chip, incluindo o firmware original carregado em fábrica (aquele que aceita os comandos AT). Embora possamos usar o SDK do fabricante para o desenvolvimento de firmwares personalizados, é muito mais fácil usar o bom e velho Arduino IDE.


Comecemos:


No Arduino IDE, abra a janela de preferências e digite a URL (marcado em vermelho na foto abaixo) no campo Additional Boards Manager URLs e selecione OK.


http://arduino.esp8266.com/stable/package_esp8266com_index.json




  • Selecione MENU → Tools → Board → Boards Manager…e vá rolando até encontrar a opção: esp8266 by ESP8266 Community , a qual deverá ser o último item da lista e clique INSTAL



Instalando USB Drivers: O USB to Serial UART module incluído no dispositivo, é o Silicon Labs’ CP2102, para o qual deveremos instalar o driver Virtual COM Port (VCP). No caso de meu MAC, o arquivo criado para comunicar com o CP2102 foi: /dev/cu.SLAB_USBtoUART. Pode encontrar o driver apropriado ao seu computador no seguinte link: CP210x USB to UART Bridge VCP Drivers


Depois de restartar o Arduino IDE , poderemos selecionar a placa no menu: Option Tools → Board → NodeMCU 1.0 (ESP-12E Module). Em seguida, especificar a correta frequência de operação da CPU: (Tools → CPU Frequency: “” → 80MHz) e velocidade de comunicação (Tools → Upload Speed: “” → 115,200). Finalmente, selecionar o port apropriado ao seu computador: (Tools → Port → /dev/cu.SLAB_USBtoUART).



Neste ponto estamos prontos para escrever nosso próprio firmware e enviá-lo ao dispositivo, mas vamos primeiramente tentar um dos exemplos incluídos com a biblioteca: File → Examples → ESP8266WiFi → WiFiScan. Após o upload, podemos abrir a janela do Serial Monitor e observar os resultados. Verifique que 115,200 baud é a velocidade selecionada no menu do canto inferior direito do Serial Monitor.



Instalando o Display OLED



Um grande companheiro para o nosso ESP-12E é o pequeno display do tipo OLED: SSD 1306. Ele será muito útil ao projeto, mostrando localmente os dados capturados, mensagens, etc. O modelo usado é um display de 128 x 64 pixels que se comunica via I2C, o SSD 1306, cujas principais características são:



  • 128 pixels na horizontal por 64 pixels na vertical. Assim se usar por exemplo, caracteres de 8×8 pixels, obteremos um display de “16X8” (8 linhas de 16 caracteres cada).

  • Comunicação via I2C : se deve conectar ao NodeMCU I2C pins, usando:


– SCL ==> D1 (equ. Arduino 5)

– SDA ==> D2 (equ. Arduino 4)


Outra característica importante do SSD1306 é que pode alimentar-lo com 3.3V gerado diretamente pelo módulo nodeMCU, como via um Power Suppley externo de 5V, que será como faremos no projeto.


Uma vez conectado o display, deve baixar e instalar sua biblioteca ao Arduino IDE. Nós usaremos a versão ACROBOT abaixo:


SSD1306 Arduino Library


Depois de ter reiniciado o IDE, a biblioteca deverá estar instalada. Carreguemos o sketch abaixo para testar o display OLED:


/***********************************************************************
* NodeMCU and OLED display "Hello World"
* Based on original code developed by: Makerbro at https://acrobotic.com/
* MJRoBot 12Oct16
************************************************************************/

#include
#include

void setup()
{
 Wire.begin();
 oled.init(); // Initialze SSD1306 OLED display
 oled.clearDisplay(); // Clear screen
 oled.setTextXY(0,0); // Set cursor position, start of line 0
 oled.putString(" MJRoBot.org");
 oled.setTextXY(4,0); // Set cursor position, start of line 4
 oled.putString(" HELLO, WORLD");
}

void loop()
{
}

Observe, que quando não definir um tamanho em pixels para os caracteres de texto, o padrão será 8X8. Para se definir um tamanho diferente, por exemplo,5X7, você poderá utilizar: oled.setFont(font5x7);



Abaixo o código para o “Hello World”:


OLED_test.ino


Captura da temperatura do ar e humidade


Um dos sensores mais utilizados para a captura de dados meteorológicos é o DHT22 (ou seu irmão, o DHT11), um sensor digital de humidade relativa do ar e temperatura. Ele usa internamente um sensor capacitivo de humidade e um termistor para medir o ar circundante, gerando um sinal digital em sua saída de dados.


De acordo com a sua folha de dados (Datasheet), o sensor deve ser alimentado entre 3.3V e 5V (algumas especificações falam em até 6V max). Ele trabalha a partir de -40 a + 80 graus centígraods (algumas especs falam em + 125 ° C) com uma precisão de +/- 0,5 ° C de temperatura e +/-2% de umidade relativa. É importante ter em mente que o seu (“sencing period”) é em média de dois segundo (tempo mínimo entre leituras).


O DHT22 tem 4 pinos (de frente para o sensor, o pino 1 é o mais esquerda):



  • VCC (5V externo)

  • Saída de dados

  • Não conectado

  • GND (Terra)



 


Uma vez que normalmente usará o sensor em distâncias inferiores a 20m, uma resistência de 10K deve ser conectado entre os pinos de dados e o VCC. O pino de saída deve ser conectado ao pino D3 do ESP-12E (veja o diagrama acima).


Uma vez que o sensor esteja instalado fisicamente no NodeMCU, baixe a biblioteca DHT a partir do repositório de programas: Adafruit github e a instale junto as outras bibliotecas de seu IDE (ambiente de desenvolvimento de programas do Arduino).


Uma vez que  recarregue o IDE, a biblioteca para o sensor de DHT deverá aparecer como instalada. Execute o código abaixo para verificar se tudo está funcionando OK:


NodeMCU_DHT22_IoT_Local_Station_OLED.ino


Capturando a humidade do solo



No projeto ArduFarmBot,  exploramos como trabalhar com um Higrômetro para medir-se a humidade do solo. Na ocasião, exploramos como desenvolver um sensor caseiro, porém aqui para explorarmos outras alternativas, usaremos um do tipo electrónico, muito comum no mercado: o sensor YL-69 + LM393 (módulo comparador). O módulo LM393 tem 2 saídas, uma digital (D0) que pode ser configurada usando-se um potenciómetro integrado e um analógico (A0). Este módulo pode ser tanto alimentado com 3.3V (o que é muito conveniente quando se trabalha com um NodeMCU), quanto com 5V externo.



  • LM393 A0: ao NodeMCU A0

  • LM393 VCC: ao VCC 5V externo (ou ao NodeMCU D8) Vide Nota abaixo *

  • LM393 GND: ao NodeMCU GND

  • LM393 D0: Não conectado



(*) É importante destacar que o correto é conectar-se o VCC do Sensor a um Pino Digital do NodeMCU, definido como saída, de maneira a que o LM393 seja “alimentado” somente quando precisemos de uma leitura. Isto é importante não apenas para economizar energia, mas também para evitar a corrosão das sondas. Utilizando-se um sensor caseiro como foi o caso no projeto ArduFarmBot original, o sensor funcionaria sem problemas, mas tendo-se que alimentar o módulo comparador, o NodeMCU apresentou problemas com o  “soilMoisterVcc” conectado. Assim, conectei o LM393 direto a VCC (5V) externo como mostrado no diagrama elétrico acima  o código não precisa ser alterado).


Abaixo, rotina para ler o sensor conectado à porta analógica:


/***************************************************
 * Get Soil Moister Sensor data
 **************************************************/
void getSoilMoisterData(void)
{
  soilMoister = 0;
  digitalWrite (soilMoisterVcc, HIGH);
  delay (500);
  int N = 3;
  for(int i = 0; i < N; i++) // read sensor "N" times and get the average
  {
    soilMoister += analogRead(soilMoisterPin);  
    delay(150);
  }
  digitalWrite (soilMoisterVcc, LOW);
  soilMoister = soilMoister/N;
  Serial.println(soilMoister);
  soilMoister = map(soilMoister, 600, 0, 0, 100);
}

Alguns comentários sobre a rotina acima:



  • O dado do sensor é capturado 3 vezes, tirando-se uma média das mesmas.

  • Usamos MAP para configurar o intervalo em percentagem. Para definir os valores extremos, procedemos como abaixo:

    – Fazer um “curto-circuito” nas pontas de prova do higrómetro, isso equivalente a “100% de h

  • humidade”, o que gerará um valor de cerca de 0 na saída do ADC

    – Colocar o higrómetro”no ar”, se observa que o valor exibido no Serial Monitor, que em meu caso foi em torno de 600.


Abaixo um código parcial para os testes até esta etapa do projeto:


FP6AH1NIU5NCAPI.ino


Capturando a temperatura do solo



Nas minhas experiências com o ArduFarmBot, descobri que existe uma relação grande entre a a humidade e a temperatura do solo. Assim, deixarei aqui opcionalmente, um sensor para temperaturas de solo, caso deseje aprofundar no assunto. Mas importante ressaltar que para o accionamento do rego, usaremos somente a temperatura do ar, proporcionada pelo DHT22.


Usaremos no projeto, uma versão impermeabilizada do sensor DS18B20. Isso é importante, pois o usaremos um solo húmido. O sensor é isolado e pode tomar medidas até 100oC , como recomendado pela Adafrut.


O DS18B20 é um sensor digital, o que o torna ideal para o uso em longas distâncias! Estes sensores digitais de temperatura tipo “1-Wire” são bastante precisos (± 0,5 ° C em grande parte da gama) e podem fornecer até 12 bits de precisão à partir de seu conversor digital-analógico integrado. Eles funcionam muito bem com o NodeMCU usando um único pino digital, e pode até mesmo conectar vários sensores no mesmo pino, pois cada um possui um ID único de 64 bits gravado de fábrica, para poder diferenciar-los.



  • O sensor funciona de 3,0 a 5,0V.

  • O sensor tem 3 fios:

    – Preto: GND

    – Vermelho: VCC

    – Amarelo: dados de 1 fio


Aqui, pode encontrar os dados completos: DS18B20 Datasheet


Para usar o DS18B20 com o IDE do Arduino, importe as bibliotecas abaixo e instale no seu IDE:





Para testar o sensor, pode usar o código “Simple.ino” incluído nos Exemplos da Biblioteca, como mostrado na foto acima. Carregue o código no seu NodeMCU e monitore a temperatura usando o Monitor Serial.



 


foto acima mostra o resultado esperado. Segure o sensor em sua mão, você deve ver a temperatura mudar para cerca de 32 / 34oC.


NOTA: A biblioteca OneWire DEVE ser uma versão especial, modificada para ser usada com o ESP8266, caso contrário receberá um erro durante a compilação. Encontrará a última versão no link acima ou no arquivo zip abaixo:



 Completando o HW



Seguindo o diagrama acima, complete o HW, instalando os botões e LEDs.


Lembre-se que ao usar os pinos que fornecem 3.3V do NodeMCU para alimentar outros dispositivos pode tornar o sistema instável devido ao consumo de corrente.Tudo bem quando temos somente um ou dois dispositivos externos, mas no caso de nosso projeto, vários componentes estão sendo utilizados. Verifique que todos os sensores (DHT22, DS18B20 e LM393 / YL69) e o Display OLED estão alimentados corretamente, através do 5V externo e o NodeMCU penas fornecendo os sinais de controle.


LEDs


Observe que os LEDs conectados ao NodeMCU são somente para serem usados como teste. Eles “simularão”, a bomba (LED vermelho) e a lâmpada (LED verde). Na configuração final, relés serão conectados a essas saídas como descrito na próxima etapa.


Botões


Com base nas leituras de sensores, um operador pode também decidir controlar manualmente a Bomba e / ou a Lâmpada. Para isso, três botões serão incorporados ao projeto:



  • VERMELHO: Ctrl da bomba manual

  • VERDE: Lâmpada manual Ctrl

  • AMARELO: Botão para leitura e apresentação de dados dos sensores (será detalhado na próxima etapa)


Os botões funcionam em modo “alterno”, ou “Toggle”. Se um atuador estiver “LIGADO”, pressionar o botão irá desligár-lo e vice-versa. A lógica do botão será “normalmente fechada”, o que significa que a Entrada NodeMCU estará constantemente “HIGH”. Pressionando o botão, um “LOW” será aplicado no pino específico.


O Diagrama abaixo resume os pinos do NodeMCU e sua conexão aos dispositivos.


Para verificar se existe um “comando local”, ou seja se um botão foi pressionado, a função readLocalCmd() deve ser executada. Esta função lê cada botão, atualizando o status das variáveis correspondentes aos estados dos atuadores (pumpStatus e lampStatus). Observe que em vez de executar diretamente um comando digitalRead (pin), a função debounce(pin) é chamada. Isso é para evitar leituras falsas do botão.


/****************************************************************
* Read local commands (Pump and Lamp buttons are normally "HIGH"):
****************************************************************/
void readLocalCmd()
{  
  boolean digiValue = debounce(PUMP_ON_BUTTON);
  if (!digiValue)
  {
    pumpStatus = !pumpStatus;
    aplyCmd();
  }

  digiValue = debounce(LAMP_ON_BUTTON);
  if (!digiValue)
  {
    lampStatus = !lampStatus;
    aplyCmd();
  }
}

No caso em que um botão é pressionado, outra função será chamada: aplyCmd (). E como o nome diz, esta aplicará o comando correspondente, ativando ou desativando os atuadores:


/***************************************************

* Receive Commands and act on actuators

****************************************************/

void aplyCmd()

{

if (pumpStatus == 1)

{

digitalWrite(PUMP_PIN, HIGH);

displayData();

}

else

{

digitalWrite(PUMP_PIN, LOW);

displayData();

}


if (lampStatus == 1)

{

digitalWrite(LAMP_PIN, HIGH);

displayData();

}

else

{

digitalWrite(LAMP_PIN, LOW);

displayData();

}

}



Considerações acerca do código:


Quando pensamos sobre o 4 grandes “grupo de tarefas” desenvolvidos até agora, podemos resumir-los em:



  • Ler Sensores

  • Ler Botões (comando local)

  • Atuar na bomba / lâmpada

  • Exibir dados


Perceberemos que o momento em que devemos realizar essas tarefas não são necessariamente os mesmos. Por exemplo, para ler os dados de temperatura e umidade do DHT 22, teremos que esperar pelo menos 2 segundos entre uma medida e outra, mas se esperamos alguns minutos, isto não fará diferença no projeto final. Para o sensor de umidade do solo, quanto menos medições fizermos, melhor (diminui a corrosão das sondas geradas por eletrólise). Mas quando pensamos nos atuadores, logo que pressionamos um botão, gostaríamos (e possivelmente precisaremos) de uma reação rápida.


Portanto, devemos usar aqui um “timer” para controlar corretamente o timing correto dessas tarefas. Poderíamos fazer isso usando o millis (), como fizemos no projeto ArdFarmBot original, mas aproveitaremos para conhecer outra ótima ferramenta, o SimpleTimer.h (siga as instruções no link ao lado para instalar a Biblioteca: SimpleTimer)


A biblioteca deve ser incluída no corpo principal do seu código, seguido de uma definição para o Timer do projeto:


 SimpleTimer timer;

Em seguida, defina os temporizadores:


timer.setInterval(1000L, readLocalCmd);       // Read buttons at every 1 second
  timer.setInterval(2000L, getSoilTempData);    // Read Soil Temp at every 2 seconds
  timer.setInterval(2000L, getDhtData);         // Read DHT Sensor at every 2 seconds
  timer.setInterval(10000, getSoilMoisterData); // Read Soil Humidity at every 10 seconds
  timer.setInterval(10000, displayData);        // Display Data at OLED at every 10 seconds

ArduFarmBot 2, “Contrôle Local”- Concluindo o código



Apresentando o Botão para Leitura dos sensores (“O amarelo”)


Como observamos na última etapa, precisaremos aguardar ciclos longos entre as medições do sensor de umidade do solo. Isto está bem para as nossas necessidades automáticas, mas para uma operação manual não vamos querer “esperar” 10, 15 ou mais segundos (ou mesmo minutos no caso real) para atualizar a leitura de um sensor. Também no mundo real, não faz sentido manter o display OLED “ACESO” ou “ON”, o tempo todo. Assim, o normal será “APAGADO” ou “OFF”.


Introduziremos esse 3 ª botão ao nosso projeto, o qual permitirá exibir os dados de leitura dos sensores a qualquer momento que quisermos, independentemente do tempo das leituras automáticas. Além disso, usaremos este mesmo botão para exibir dados no OLED quando os sensores forem atualizados. Abaixo da função readLocaCmd () alterada para interação com o novo botão:


/**************************************************************************
* Read local commands (Pump, Lamp and Sensor buttons are normally "HIGH"):
**************************************************************************/
void readLocalCmd()
{  
  boolean digiValue = debounce(PUMP_ON_BUTTON);
  if (!digiValue)
  {
    pumpStatus = !pumpStatus;
    aplyCmd();
  }

  digiValue = debounce(LAMP_ON_BUTTON);
  if (!digiValue)
  {
    lampStatus = !lampStatus;
    aplyCmd();
  }

  digiValue = debounce(SENSORS_READ_BUTTON);
  if (!digiValue)
  {
    turnOffOLED = !turnOffOLED;
    if (!turnOffOLED)
    {
      oled.setTextXY(0,0); oled.putString("UPDATING SENSORS");
      getDhtData();
      getSoilMoisterData();
      getSoilTempData();
      oledStart();
      displayData();
    }else oled.clearDisplay(); //turn off OLED
  }
}

Neste ponto, todo o HW está completado (usando-se LEDs como atuadores) e temos portanto todas as peças de SW à serem montadas.


O vídeo mostra o ArduFarmBot 2, operando em modo Local e Manual:



Poderá fazer o download do código a ser utilizado na versão “Controle local”, diretamente em meu repositório:  GitHub: ArduFarmBot2_Local_Manual_Ctrl_V1


Automatizando nosso sistema de jardinagem



Neste ponto, todos os componentes do HW estão no lugar e como se viu na etapa anterior, o ArduFarmBot 2 pode ser controlado localmente por um operador através dos botões. O que falta agora é definir-se a “lógica” que permitirá ao nosso sistema realizar a tarefa de irrigar a plantação automaticamente! Para isto, precisamos incluir algum “cérebro” ao nosso projeto.


Para começar, definamos o intervalo inicial onde funcionarão os sensores. Esses valores devem ser alterados mais tarde usando-se valores práticos a serem obtidos em uma plantação real:


Humidade do solo:



  • “HÚMIDO”: Mais de 88% (não regar)

  • “IDEAL”: Entre 66% e 88% (Onde queremos trabalhar)

  • “SECO”: abaixo de 66% (necessário ligar a bomba para aumentar a humidade)


Temperatura do ar:



  • “FRIO”: Abaixo de 12oC (Ligar a lâmpada para gerar calor)

  • “IDEAL”: entre 12oC e 22oC

  • “QUENTE”: Acima d 22oC (não ligar a lâmpada)


Deve levar em conta que cada tipo de semente possui um intervalo ótimo de temperatura onde germinarão mais rapidamente. Por exemplo, para tomates o tempo mínimo para germinar as sementes será de 6 dias em temperaturas entre 20 e 25 oC, sendo que esta quantidade de dias aumentará para temperaturas inferiores ou superiores (mais de 43 dias para temperaturas inferiores a 10oC e 9 dias para temperaturas superiores a 35oC.


Poderá verificar mais informações sobre este relacionamento (Temp / dias de germinação) no link abaixo:


The effect of soil temperature on seeds germination


Uma vez de posse desses dados: temperatura do ar, umidade do ar, umidade do solo e temperatura do solo, poderemos construir uma matriz complexa definindo como queremos que o nosso sistema de jardinagem automático funcione.


Definamos os parâmetros à serem usados em nosso código:


/* Automatic Control Parameters Definition */
#define DRY_SOIL      66
#define WET_SOIL      85
#define COLD_TEMP     12
#define HOT_TEMP      22
#define TIME_PUMP_ON  15
#define TIME_LAMP_ON  15

TIME_PUMP_ON e TIME_LAMP_ON são definidos como o tempo em segundos que a bomba e a lâmpada devem permanecer LIGADAS durante a operação automática.


Com base nos parâmetros acima, pensemos em algumas suposições muito simples a serem implementadas no código:



  • Se o solo estiver seco: (DRY) ==> Ligar a bomba (PUMP = ON)

  • Se a temperatura estiver fria (COLD) ==> Ligar a lâmpada (LAMP = ON)


O código:


Criemos uma nova função, que com base na leitura dos sensores lidará automaticamente com os atuadores, ligando / desligando a bomba e a lâmpada: autoControlPlantation (). Esta função conforme mostrado abaixo, será chamada em todas os ciclos de leitura de sensores:


/**************************************************************
* Automatically Control the Plantation based on sensors reading
**************************************************************/
void autoControlPlantation(void)
{
  if (soilMoister < DRY_SOIL)
  {
    turnPumpOn();
  }

  if (airTemp < COLD_TEMP)
  {
    turnLampOn();
  }
}

A função tem duas tarefas básicas:



  • Controlar a bomba

  • Controlar a lâmpada


Abaixo as duas funções de controle chamadas a partir da função autoControlPlantation ():


***************************************************
* Turn Pump On for a certain amount of time
****************************************************/
void turnPumpOn()
{
  pumpStatus = 1;
  aplyCmd();
  delay (TIME_PUMP_ON*1000);
  pumpStatus = 0;
  aplyCmd();
}

/***************************************************
* Turn Lamp On for a certain amount of time
****************************************************/
void turnLampOn()
{
  lampStatus = 1;
  aplyCmd();
  delay (TIME_LAMP_ON*1000);
  lampStatus = 0;
  aplyCmd();
}

Por fim, usaremos o botão Sensor Read (“amarelo”) para não só interromper o programa durante um certo tempo durante a inicialização, mas também para exibir os parâmetros iniciais mais importantes, como mostrado na foto acima.


Neste ponto, o ArduFarmBot está totalmente funcional em termos de HW e SW.


O vídeo mostra o ArduFarmBot 2, operando em modo Local e Automático:



O código para a versão  “Local e Automático” do ArduFarmBot2 pode ser descarregada  de meu depositário:  GitHub: ArduFarmBot2_Local_Automatic_Ctrl_V2.


 Criando a App BLYNK



É realmente muito fácil de se construir projetos IoT usando o BLYNK. A primeira coisa que você precisará, é ter a aplicação BLINK instalada no telefone e sua biblioteca instalada no IDE do Arduino. Se ainda não as tiver, siga os passos abaixo:



Uma vez que o Arduino IDE é recarregado, deve estar OK para começar a usar BLINK em seu projeto IoT.


Agora, vamos abrir o aplicativo “Blynk”  no smartphone:



  1. Clique na tela Create New Project

  2. De um nome para seu projeto (Por exemplo: “ArduFarmBot 2”)

  3. Selecione o HW apropriado: NodeMCU

  4. Anote seu código do Authorization Token (você pode enviar-lo por e-mail e copiar-lo em seu código):
    char auth[] = "YourAuthToken";


  5. Pressione OK. Uma tela vazia cheia de pontos irá aparecer.

  6. Clique na tela para abrir o Widget Box


OK, vamos tomar um momento e pensar sobre o nosso ArduFarmBot 2 Blynk App e definir quais serão os Widgets a serem instalados. Revisitando a especificação geral descrita na introdução do projeto, podemos resumir que o nosso aplicativo precisará:



  • Ler todos os sensores e verificar o status dos atuadores

  • Tomar ações remotas, como “ligar / desligar” a bomba e a lâmpada

  • Enviar mensagens quando o sistema estiver “off-line” e / ou um atuador for ligado

  • Registrar a história de leitura dos sensores


De maneira a organizar as coisa, vamos dividir as tarefas descritas acima em 3 Tabs:



  • SENSORS



  • ACTUATORS / CONTROL



  • GRAPHICS


“Tabs” será o primeiro Widget a ser instalado. Uma vez selecionado, defina “Tab names” como acima.


Em seguida, entre em cada um dos Tabs criados e instale os Widgets como descritos abaixo:


SENSORS



  • Gauge: “Temp Air [oC]” Blue; input: V10 0 to 50; frequency: 5 sec



  • Gauge: “Humidity Air [%]” Green; input: V11 0 to 100; frequency: 5 sec



  • Gauge: “Soil Humidity [%]” Red; input: V12 0 to 100; frequency: 5 sec



  • Gauge: “Soil Temperature[oC]” Yellow; input: V13 -10 to 50; frequency: 5 sec



  • LED: “PUMP” Red; V0



  • LED: “LAMP” Green; V1



ACTUATORS / CONTROL



  • Button: “PUMP” Red; output: V3 0 to 1; mode: Switch; label: on: ACT, off: OK



  • Button: “LAMP” Green; output: V4 0 to 1; mode: Switch; label: on: ACT, off: OK



  • LED: “PUMP” Red; V0



  • LED: “LAMP” Green; V6



  • Notifications: Notify When HW goes offline: ON



GRAPHICS




  • Data to Show:



  • V10 “Temp Air”



  • V11 “Humidity Air”



  • V12 “Soil Humidity “



  • V13 “Soil Temp”



Alterando o código para introduzir as funcionalidades do Blynk



Para executar um aplicativo Blynk juntamente com seu código, precisará:



  • Incluir a biblioteca BlynkSimpleEsp8266 no início do seu código

  • Durante o setup(), inicie com as credenciais do Blynk: Blynk.begin (auth, ssid, pass);

  • Defina uma temporização para enviar dados locais para o servidor Blynk: timer.setInterval (5000L, sendUptime);

  • Dentro do loop (), execute a função Blynk.run();

  • Crie a função sendUptime (); Onde você introduzirá os dados do sensor a serem

  • enviados ao Blynk Server: Blynk.virtualWrite (VirtualPin, dados do sensor);

  • O código final deverá incluir agora um novo arquivo: “StationCredentials.h”:


char auth[] = "YOUR PROJECT TOKEN"; // Blynk project: "ArduFarmBot2"
char ssid[] = "YOUR LOCAL WIFI NAME";
char pass[] = "YOUR WIFI PASSWORD";

Outras considerações:


Para usar um Widget do tipo: “Virtual LED” na app do Blynk, você necessitará definir-lo no início do código:


WidgetLED PUMPs(V0);  // Echo signal to Sensors Tab at Blynk App
WidgetLED PUMPa(V5); // Echo signal to Actuators Tab at Blynk App
WidgetLED LAMPs(V1);  // Echo signal to Sensors Tab at Blynk App
WidgetLED LAMPa(V6); // Echo signal to Actuators Tab at Blynk App

Para acender ou apagar o LED relacionado com a Bomba (PUMPs LED) que está conectado ao virtual PIN V0 por exemplo, chame as funções correspondentes abaixo:



  • PUMPs.on() ou

  • PUMPs.off()


Incluiremos os comandos na função applyCmd (), de maneira que os LEDs na app Blynk irão imitar os LEDs reais de nosso projeto. Também deveremos incluir o comando: Blynk.notify (“Mensagem a ser enviada”); na mesma função applyCmd (), uma para a Bomba e outra para a Lâmpada. Abaixo, a nova função:


/***************************************************
* Receive Commands and act on actuators
****************************************************/
void aplyCmd()
{
  if (pumpStatus == 1)
  {
    Blynk.notify("ArduFarmBot2: Warning ==>> Pump ON");
    digitalWrite(PUMP_PIN, HIGH);
    if (!turnOffOLED) displayData();
    PUMPs.on();
    PUMPa.on();
  }
  else
      {
        digitalWrite(PUMP_PIN, LOW);
        if (!turnOffOLED) displayData();
        PUMPs.off();
        PUMPa.off();
      }
 
  if (lampStatus == 1)
  {
    Blynk.notify("ArduFarmBot2: Warning ==>> Lamp ON");
    digitalWrite(LAMP_PIN, HIGH);
    if (!turnOffOLED) displayData();
    LAMPs.on();
    LAMPa.on();
  }
  else
      {
        digitalWrite(LAMP_PIN, LOW);
        if (!turnOffOLED) displayData();
        LAMPs.off();
        LAMPa.off();
      }
}


Para receber um comando a partir de um botão (Widget button) incluído na app Blynk, uma função BLYNK_WRITE () deve ser definida fora de uma função, loop () ou setup (). Para isso foi criado o código abaixo, um para cada Botão Blynk (PUMP e LAMP):


/****************************************************************
* Read remote commands
****************************************************************/
BLYNK_WRITE(3) // Pump remote control
{
  int i=param.asInt();
  if (i==1)
  {
    pumpStatus = !pumpStatus;
    aplyCmd();
  }
}

BLYNK_WRITE(4) // Lamp remote control
{
  int i=param.asInt();
  if (i==1)
  {
    lampStatus = !lampStatus;
    aplyCmd();
  }
}

Abaixo, o vídeo mostra a operação automática do ArduFarmBot 2, agora incluíndo o Blynk:





O código para o ArduFarmBot2 em sua versão “Remote and Automatic control”, usando o Blynk pode ser descarregada de meu repositório:  GitHub: ArduFarmBot2_Ext_Auto_Ctrl__V3_0



Relés como atuadores



Como discutido na introdução, nosso objetivo final será cuidar de uma plantação. Com os dados fornecidos pelos sensores, vamos saber a temperatura do ar e do solo, humidade relativa do ar e o mais importante, quão “seco” está o solo. Com esses dados na mão, o nosso programa deve calcular se é necessário irrigar a plantação ligando uma bomba de água ou acender uma lâmpada elétrica para fornecer o calor adequado para a cultura.



Para isso, usaremos um pequeno módulo de relé de 5V tanto para a ativação da bomba quanto da lâmpada.


O circuito do diagrama do módulo de relé pode ser visto abaixo:



Pelo diagrama, devemos conectar :



  • Power Supply 5V ==> (4) “Vcc”

  • NodeMCU D6 ==> (3) “IN1” (Pump)

  • NodeMCU D7 ==> (2) “IN2” (Lamp)

  • NodeMCU GND ==> (1) “GND”


Normalmente encontramos como saída, 3 pinos para cada relé: “NO” (“Normal Open“), “Ref” or “COM” (“Reference” or “Common“) and “NC” (“Normal Closed“). Usaremos o NO e o COM para cada relé.


No exemplo abaixo, o “COM” é o terminal para conectar ao pino positivo externo da fonte de alimentação de 5V(no caso da bomba (ou do 220VAC para a lâmpada). O “NO” será conectado à Bomba (ou Lâmpada).



No caso do relé escolhido e confirmado pelo diagrama acima, normalmente o IN1 e o IN2 devem estar em ALTO e sua ativação acontecerá com um nível BAIXO (menos de 2V). Com um nível BAIXO na saída do NodeMCU, a corrente fluirá de VCC para o pino D6 do NodeMCU, ativando a entrada do optoacoplador. O solenóide será acionado, “fechando” a saída NO (normalmente aberta) do relé, o que ligará a bomba.


Em relação a versão V3.0 do código desenvolvida na etapa anterior, deveremos “inverter”a logica de acionamento dos atuadores (ou pinos digitais como saída). Os pinos D6 e D7 do NodeMCU deverão estar normalmente em HIGH. Assim a função de setup(), deverá ser alterada:


digitalWrite(PUMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
digitalWrite(LAMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)

Também deveremos alterar a função applyCmd():


/***************************************************
* Receive Commands and act on actuators
****************************************************/
void aplyCmd()
{
  if (pumpStatus == 1)
  {
    Blynk.notify("ArduFarmBot2: Warning ==>> Pump ON");
    digitalWrite(PUMP_PIN, LOW); // To be used with Relay module (inverted logic: activate with LOW)
    if (!turnOffOLED) displayData();
    PUMPs.on();
    PUMPa.on();
  }
  else
      {
        digitalWrite(PUMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
        if (!turnOffOLED) displayData();
        PUMPs.off();
        PUMPa.off();
      }
 
  if (lampStatus == 1)
  {
    Blynk.notify("ArduFarmBot2: Warning ==>> Lamp ON");
    digitalWrite(LAMP_PIN, LOW); // To be used with Relay module (inverted logic: activate with LOW)
    if (!turnOffOLED) displayData();
    LAMPs.on();
    LAMPa.on();
  }
  else
      {
        digitalWrite(LAMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
        if (!turnOffOLED) displayData();
        LAMPs.off();
        LAMPa.off();
      }
}

O código para o ArduFarmBot2 em sua versão “Remote and Automatic control”, usando o Blynk e relés (ativos com “LOW”)pode ser baixado desde meu repositório: Github: ArduFarmBot2_Ext_Auto_Ctrl__V4_0


Teste real com o ArduFarmBot 2



A Bomba escolhida é uma mini-bomba 5V DC para água (funciona “afogada”).



Pode instalá-lo submerso em água ou “inline”. Usaremos o segundo método:



Ligue um dos fios da bomba ao relé IN1 e o outro ao pino de alimentação externa de 5V (+). Pegue o pino de alimentação (-) e ligue-o ao relé COM1.


O filme abaixo mostra o ArduFarmBot 2 operando em modo manual (local e remoto):



E finalmente, o vídeo abaixo mostra sua operação em modo automático:




Artigo gentilmente cedido por: MJRoBot.Org


 


Todos os produtos utilizados neste artigo podem ser encontrados na Loja de Eletrónica e Robótica – ElectroFun.


Gostaram deste artigo? Deixem o vosso comentário no formulário a baixo e partilhem com os vossos amigos.


Não se esqueçam de fazer like na nossa Página no Facebook.


Podem ainda colocar as vossas dúvidas no nosso Forum da Comunidade Arduino em Portugal ou no nosso Grupo no Facebook Arduino Portugal – Qual o teu projeto?




Comments

Comentários



8
[html]Do “blink” ao BLYNK, uma viagem pela “Internet das coisas” nas asas do NodeMCU ESP-12E


         
      


Neste tutorial, aprenderemos a lidar com este fantástico dispositivo, o NodeMCU ESP-12E Development Kit V. 1.0, onde aprenderemos como:



  • Fazer piscar um LED pela internet

  • Ligar o ESP a um display LCD do tipo “OLED”

  • Capturar dados gerados por sensores tanto analógicos como digitais

  • Subir dados a um serviço de Internet das coisas tal como o Thinkspeak

  • Controlar “coisas” pela internet, utilisando-se aplicativos para smartphones como o BLINK






1: Lista de Material




  1. Node MCU ESP-12E Development Kit V 1.0

  2. 0.96″ I2C IIC SPI Serial 128X64 Yellow&Blue OLED LCD LED Display

  3. DHT22 AM2302 Temperature And Humidity Sensor

  4. YL-69 sensor and LM393 Comparator module soil medium Hygrometer,

  5. Breadboard

  6. LED

  7. Resistor 10K ohms

  8. Cabos






2: O NodeMCU


nodeMCU.jpg


O NodeMCU ESP-12E é a versão integrada do popular ESP8266, um Serial to Wi-Fi System On a Chip (SoC), que apareceu pela primeira vez em 2013 e lançado no mercado já no ano seguinte. O ESP8266 foi desenvolvido pela empresa chinesa com sede em Shangai, Espressif Systems, uma fabricante de circuitos integrados focada no desenvolvimento de chips de RF, particularmente Wi-Fi.


Existem vários módulos no mercado que se utilizam do chip ESP8266, Eles são nomeados ESP-NN, onde NN é um número 01, 02, … .. 12, etc. e as vezes seguido de uma letra. Estes módulos tipicamente possuem: o ESP8266 SoC, memória flash, um cristal e na maioria dos casos, uma antena. No link você pode encontrar a lista completa de dispositivos baseados  no ESP8266 encontradas no mercado: Família ESP8266 .


Os 2 módulos mais importantes são sem dúvida, a ESP-01 e o ESP-12E.


O ESP-01 têm sido amplamente utilizado em projetos da Internet das coisas onde tamanho e custo, mas não número de GPIOs (há apenas 2 do tipo digital disponíveis) são importantes. Exploramos este módulo em vários outros tutoriais aqui no Blog:


O ESP8266 – Parte 1Parte 2Parte 3


O ESP-12E Development Board (NodeMCU DevKit 1.0)


Para aumentar ainda mais a capacidade de utilização do módulo ESP-12E, foram adicionados regulação de potência e conectividade USB. O ESP-12E inclui:



  • Adaptador USB para UART: Silicon Labs CP2102,

  • NCP1117 3,3VDC Voltage Regulator,

  • Conector micro-USB,

  • Pinos adicionais com GND, Vin, 3,3VDC para facilitar o acesso durante o desenvolvimento.


Em suma, o NodeMCU ESP-12E é um dispositivo pronto para ser usado, bastando que você instale os drivers USB ao seu computador e comece a escrever programas que se conectam à sua rede Wi-Fi !


Especificações Técnicas:



  • Support STA/AP/STA+AP 3 working modes;

  • Built-in TCP/IP protocol stack, support multiple-channel TCP Client connection (max 5);

  • 0~D8, SD1~SD3: used for GPIO, PWM (D1-D8), IIC, ect; the driven ability can be arrived at 15mA;

  • AD0: one-way 10 bits ADC;

  • Power input: 4.5V~9V(10VMAX), support USB powered and USB debug;

  • Working current: ≈70mA(200mA MAX, continue), standby<200uA;

  • Transmission data rate: 110-460800bps;

  • Support UART/GPIO data communication interface;

  • Support update firmware remotely (OTA);

  • Support Smart Link;

  • Working temperature:-40℃~+125℃;

  • Driven mode: double large-power H bridge driven

  • Weight: 7g.

  • Picture of The NodeMCU




  • Um excelente site para se aprender mais sobre a família do ESP 8266 é: What Is The ESP8266 And Why Is It So Popular?





    3: Instalando o NodeMCU ao IDE do Arduino




    Se você deseja programar e usar o NodeMCU como se fosse um Arduino, a boa notícia é que é possível escrever-se firmwares personalizados e carregá-los no chip (“flash-it”). É importante lembrar que qualquer novo “firmware personalizado” irá substituir qualquer coisa previamente armazenada na memória flash do chip, incluindo o firmware original carregado em fábrica (aquele que aceita os comandos AT). Embora possamos usar o SDK do fabricante para o desenvolvimento de firmwares personalizados, é muito mais fácil usar o bom e velho Arduino IDE.


    Comecemos:


    No Arduino IDE,  abra a janela de preferências e digite a URL (marcado em vermelho na foto abaixo) no campo Additional Boards Manager URLs e selecione OK.


    http://arduino.esp8266.com/stable/package_esp8266com_index.json


    Picture of Installing the NodeMCU board at Arduino IDE



    • Selecione MENU  Tools → Board → Boards Manager…e vá rolando até encontrar a opção: esp8266 by ESP8266 Community , a qual deverá ser o último item da lista e clique INSTALLarduino_ide_boards_esp8266

    • Instalando USB Drivers: O USB to Serial UART module incluído no dispositivo, é o  Silicon Labs’ CP2102, para o qual deveremos instalar o driver Virtual COM Port (VCP). No caso de meu MAC, o arquivo criado para comunicar com o CP2102 foi:  /dev/cu.SLAB_USBtoUART. Você pode encontrar o driver apropriado ao seu computador no seguinte link: CP210x USB to UART Bridge VCP Drivers

    • Depois de restartar o Arduino IDE , poderemos selecionar a placa no menu: Option Tools → Board → NodeMCU 1.0 (ESP-12E Module). Em seguida, especificar a correta frequência de operação da CPU: (Tools → CPU Frequency: “” → 80MHz) e velocidade de comunicação (Tools → Upload Speed: “” → 115,200). Finalmente, selecionar o port apropriado ao seu computador: (Tools → Port → /dev/cu.SLAB_USBtoUART).

    • nodemcu-ide-setup-3

    • Neste ponto estamos prontos para escrever nosso próprio firmware e enviá-lo ao dispositivo, mas vamos primeiramente tentar um dos exemplos incluídos com a biblioteca: File → Examples → ESP8266WiFi → WiFiScan. Após o upload, podemos abrir a janela do Serial Monitor e observar os resultados. Verifique que 115,200 baud é a velocidade selecionada no menu do canto inferior direito do Serial Monitor.

    • nodemcu-ide-setup-4

      4: Piscando (“Blinking”) o LED



    • FullSizeRender 24.jpg

    • O “Olá Mundo” de qualquer novo projeto de HW é sem dúvida alguma, um LED piscando. Para conectar-se um LED em seu ESP-12E, você poderá usar qualquer um dos seus GPIO digitais.

    • Picture of Blinking a LED

    • O diagrama de pinos acima mostra o layout da 2ª geração do NodeMCU ESP8266 . Em nosso caso, usaremos o pino D7 ou seu equivalente para Arduino: GPIO13.

    • blink.png

    • Você poderá testar o código usando tanto “D7” quanto “13”. ambas formas funcionarão. O pino D7 não precisa de um resistor externo para alimentar o LED, pois possui um internamente. Abaixo um código simples para piscar o LED:








 
/**********************************************
  Blink
  Connected to pin D7 (GPIO13) ESP8266 NODEMCU
 **********************************************/

#define ledPin 13
// #define ledPin D7

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  digitalWrite(ledPin, HIGH);  
  delay(1000);              
  digitalWrite(ledPin, LOW);    
  delay(1000);            
}
 



Há uma relação entre alguns dos pinos do NodeMCU e do Arduino, automaticamante identificados pelo IDE, tal como descrito abaixo:



  • ESP ==> Arduino

  • D0 ==> 16

  • D1 ==> 5

  • D2 ==> 4

  • D3 ==> 0

  • D4 ==> 2

  • D5 ==> 14

  • D6 ==> 12

  • D7 ==> 13

  • D8 ==> 15

  • D9 ==> 3

  • D10 ==> 1


Abaixo o código pronto para ser executado no IDE do Arduino:







5: Instalando o display de 0.96″ (OLED)


FullSizeRender 25.jpg


Um grande companheiro para o nosso ESP-12E é o pequeno display do tipo OLED: SSD 1306. Ele pode ser muito útil em projetos tanto para mostrar seus dados ou mensagens, quanto para depurar seus programas em campo. O modelo que usei aqui é um display de 128 x 64 pixels que se comunica via I2C, o SSD 1306, cujas principais características são:



  • 128 pixels na horizontal por 64 pixels na vertical. Assim se você usar por exemplo, caracteres de  8×8 pixels, obteremos um display de “16X8” (8 linhas de 16 caracteres cada).

  • Comunicação via I2C : se deve conectar ao NodeMCU I2C pins, usando:

    • SCL ==> D1 (equ. Arduino 5)

    • SDA ==> D2 (equ. Arduino 4)




Outra característica importante do SSD1306 é que você deve alimentar-lo com 3.3V, pelo que é possível conectar-lo diretamente ao módulo nodeMCU, como mostra o diagrama eléctrico abaixo:


Picture of Using the 0.96


Uma vez conectado o display, baixar e instalar a sua biblioteca em nosso Arduino IDE. Nós usaremos a versão ACROBOT abaixo:


SSD1306 Arduino Library


Depois de ter reiniciado o IDE, a biblioteca deverá estar instalada. Carreguemos o sketch abaixo para testar o display OLED:



 
/***********************************************************************
*  NodeMCU and OLED display "Hello World"
*  Based on original code developed by: Makerbro at  https://acrobotic.com/

*  MJRoBot 12Oct16
************************************************************************/

#include
#include

void setup()
{
  Wire.begin();  
  oled.init();                      // Initialze SSD1306 OLED display
  oled.clearDisplay();              // Clear screen
  oled.setTextXY(0,0);              // Set cursor position, start of line 0
  oled.putString("  MJRoBot.org");
  oled.setTextXY(4,0);              // Set cursor position, start of line 4
  oled.putString("  HELLO, WORLD");
}

void loop()
{
}
 



Observe que quando você não definir um tamanho em pixels para os caracteres de texto, o padrão será 8X8. Para se definir um tamanho diferente, por exemplo,5X7, você poderá utilizar: oled.setFont(font5x7);


Abaixo o código para o “Hello World”:








6: O NodeMCU e o DHT22 como uma estação climática


57fe5c32937ddb5b790007f3.jpeg


 





Picture of NodeMCU as a local weather station using DHT22





Um dos sensores mais utilizados normalmente para se captar dados meteorológicos é o DHT22 (ou seu irmão, o  DHT11), um sensor digital de humidade relativa do ar e temperatura. Ele usa internamente um sensor capacitivo de humidade e um termistor para medir o ar circundante, gerando um sinal digital em sua saída de dados. 


De acordo com a sua folha de dados (Datasheet), o sensor deve ser alimentado entre 3.3V e 5V (algumas especificações falam em até 6V max). Ele trabalha a partir de -40  a + 80 graus centígraods (algumas especs falam em + 125 ° C) com uma precisão de +/- 0,5 ° C de temperatura e +/-2% de umidade relativa. É importante ter em mente que o seu (“sencing period”) é em média de dois segundo (tempo mínimo entre leituras).


O site da Adafruit fornece uma série de informações sobre ambos, DHT22 e seu irmão DHT11. Para mais detalhes, visite a página:  Tutorial DHT22 / 11.


O DHT22 tem 4 pinos (de frente para o sensor, o pino 1 é o mais esquerda):



  1. VCC (3 a 5V)

  2. saída de dados

  3. Não conectado

  4. GND (Terra)

  5. OLED_DHT22.png




  6. Uma vez que normalmente você usará o sensor em distâncias inferiores a 20m, um resistor de 10K deve ser conectado entre os pinos de dados e o VCC. O pino de saída deve ser conectado ao pino D3 do ESP-12E (veja o diagrama acima).


    Uma vez que o sensor esteja instalado fisicamente no NodeMCU, baixe a biblioteca DHT a partir do repositório de programas:  Adafruit github e a instale junto as outras  bibliotecas de seu IDE (ambiente de desenvolvimento de programas do Arduino).


    Uma vez que você recarregue o IDE, a biblioteca para o  sensor de DHT deverá aparecer como instalada. Execute o código abaixo para verificar se tudo está funcionando OK:








    7: Instalando sensores analógicos


    57fe81bf50e1b6b8d60002fc.jpeg


    O NodeMCU possui um Analog Digital Converter (ADC) de 10 bits integrado. Quando comparado com um Arduino UNO que tem 6 ADCs “portas” ou o Nano que tem 8, parece que o NodeMCU sai perdendo aqui. Mas isto não é necessariamente verdade. Primeiro, os Arduinos UNO ou Nano em realidade, possuem apenas um ADC integrado internamente o qual deve ser multiplexado para se poder ler suas múltiplas entradas analógicas. Então, podemos fazer exatamente o mesmo com o NodeMCU.


    Por exemplo, suponha que você necessite ler 2 sensores analógicos:



    • Higrômetro (Soil Moisture) para se medir a umidade do solo (Sensor 1)

    • LDR: para se medir a intensidade da luz ou um segundo higrômetro (Sensor 2)


    O que devemos fazer é criar um “multiplexador”, “alimentando-se individualmente cada um desses sensores a cada vez que precisemos ler um deles. Para isso você deve definir para cada sensor, uma das GPIOs digitais como saída, colocando-as em nível ALTO em cada leitura.


    Analog Sensor Mux


    Por exemplo, o código abaixo daria conta do recado:







 
#include

int sensorPin = A0;    // analog input for both sensors
int enable1 = D1;      // enable reading Sensor 1
int enable2 = D2;      // enable reading Sensor 2

int sensorValue1 = 0;  // variable to store the value coming from sensor 1
int sensorValue2 = 0;  // variable to store the value coming from sensor 2

void setup()
{
  Serial.begin(115200);
  delay(10);
  pinMode(enable1, OUTPUT);
  pinMode(enable2, OUTPUT);
}

void loop()
{
// Sensor 1
  digitalWrite(enable1, HIGH);
  sensorValue1 = analogRead(sensorPin);
  sensorValue1 = constrain(sensorValue1, xxx, yyy);
  sensorValue1 = map(sensorValue1, xxx, yyy, 0, 1023);
  Serial.print("Sensor 1 value:  ");
  Serial.println(sensorValue1);
  digitalWrite(enable1, LOW);
  delay(100);

// Sensor 2

  digitalWrite(enable2, HIGH);
  delay(500);
  sensorValue2 = analogRead(sensorPin);
  sensorValue2 = constrain(sensorValue2, xxx, yyy);
  sensorValue2 = map(sensorValue2, xxx, yyy, 1023, 0);

  Serial.print("Sensor 1 value:  ");
  Serial.println(sensorValue2);
  Serial.println();
  delay(100);

  digitalWrite(enable2, LOW);
}
 

Para saber mais sobre múltiplas entradas analógicas, consulte o site: Multiple analog inputs using one analoge pin


Higrômetro:


Picture of Using Analog sensors No Projeto ArduFarmBot, exploramos como trabalhar com um higrômetro para medir a umidade do solo. Lá, desenvolvemos um sensor do tipo DIY (“Do it yourself” – “Faça você mesmo”), mas aqui vamos usar um eletrônico, muito comum no mercado: o par sensor YL-69 e o comparador LM393.


O módulo LM393 possui 2 saídas, uma digital (D0), que pode ser configurada usando-se o potenciômetro que existe integrado ao módulo e um analógico (A0). Este módulo pode ser alimantado com 3.3V, o que é muito conveniente quando se trabalha com um NodeMCU. O que vamos fazer, é instalar os 4 pinos do LM393  como descrito abaixo:



  • LM393 A0:    to NodeMCU A0 input

  • LM393 VCC: to NodeMCU VCC or to NodeMCU GPIO D3*

  • LM393 GND: to NodeMCU GND

  • LM393 D0:    Não conectado

  • NodeMCU WS V2.png

  • Note que no diagrama acima, um sensor de humidade equivalente de 3 pinos  foi usada apenas para referência (não encontrou o módulo apropriado para desenha-lo com o Fritzing). Também é importante notar que o o “VCC do Sensor” deve ser conectado a um pino digital como saída, de modo que o LM393 seja alimentado apenas quando precisemos fazer uma leitura. Isto é importante não só para poupar energia, mas também para proteger as sondas de corrosão.* Eu deixei aqui as 2 opções para alimentar sensor, porque pelo menos no caso de meu sensor e módulo, percebi que o NodeMCU não carregava o sketch com o D3 conectado. Também tive eventuais erros devido ao consumo de energia. Se você alimentar o LM393 diretamente ao 3.3V, o código não precisa ser alterado.Uma rotina simples pode ser escrita para se ler a porta analógica:


 
/***************************************************
 * Get Soil Moister Sensor data
 **************************************************/
void getSoilMoisterData(void)
{
  soilMoister = 0;
  digitalWrite (soilMoisterVcc, HIGH);
  delay (500);
  int N = 3;
  for(int i = 0; i < N; i++) // read sensor "N" times and get the average
  {
    soilMoister += analogRead(soilMoisterPin);  
    delay(150);
  }
  digitalWrite (soilMoisterVcc, LOW);
  soilMoister = soilMoister/N;
  Serial.println(soilMoister);
  soilMoister = map(soilMoister, 380, 0, 0, 100);
}
 



Alguns comentários sobre a rotina acima:



  • Os dados do sensor é capturado 3 vezes, tirando-se uma média das mesmas.

  • Usamos MAP para configurar o intervalo em percentagem. Para definir os valores extremos, procedemos como abaixo:

    • Fazer um “curto-circuito” nas pontas de prova do higrômetro, isso equivalente a “100% de umidade”, o que gerará um valor de cerca de 0 na saída do ADC

    • Colocar o higrômetro”no ar”, se observa que o valor exibido no Serial Monitor é em torno de 380.




Abaixo o código completo para esta fase do projeto:








8: Subindo os dados para a nuvem: ThinkSpeak.com



Até agora, utilizamos o NodeMCU ESP12-E como se fosse uma placa normal de Arduino. É claro que apenas “tocamos” o verdadeiro potencial deste espectacular chip e agora é a hora de decolarmos rumo as estrelas! Quer dizer, para a nuvem!


9
Projetos / O ESP8266 parte 1 – Serial WIFI Module
« Online: Dezembro 08, 2017, 09:23:28 am »
[html]O ESP8266 parte 1 – Serial WIFI Module


         
      

O ESP8266 é talvez o mais versátil modulo serial para se ligar “coisas” a internet, daí ele ser tão popular no mundo do IoT. Ele é um modulo completo, que inclui um microprocessador que pode ser programado diretamente via o IDE do Arduino (em C++), ou noutros ambientes para compilação (usualmente usando uma linguagem de alto nível própria, o “Lua”). Para se controlar “coisas”, não há necessidade de se ter o Arduino propriamente dito para a interface, pois o ESP8266 possui 2 GPIOs (dois “pinos” de entrada/saída).


Link para o Forum específico do ESP8266


Features:



  • 802.11 b/g/n

  • Wi-Fi Direct (P2P), soft-AP

  • Integrated TCP/IP protocol stack

  • Integrated TR switch, balun, LNA, power amplifier and matching network

  • Integrated PLLs, regulators, DCXO and power management units

  • +19.5dBm output power in 802.11b mode

  • Power down leakage current of <10uA

  • 1MB Flash Memory

  • Integrated low power 32-bit CPU could be used as application processor

  • SDIO 1.1 / 2.0, SPI, UART

  • STBC, 1×1 MIMO, 2×1 MIMO

  • A-MPDU & A-MSDU aggregation & 0.4ms guard interval

  • Wake up and transmit packets in < 2ms

  • Standby power consumption of < 1.0mW (DTIM3)


Meio cheio de palavrões acima, mas é bom ter a mão “just in case”.


Até hoje, eu somente estudei o ESP8266 junto com o Arduino, substituindo a necessidade de um relativamente caro shield para wiFi (Shield, são umas plaquinhas que se instalam ao Arduino para expandir suas capacidades).  Ainda não brinquei com a menina no modo “stand alone”, isso ficará para um post mais adiante. A propósito, o ESP8266 é realmente uma menina bonita e prendada, mas como todas elas, dão um trabalho ………


10
O “Mars Rover” tupiniquim – Protótipo de uma estação móvel para captura de dados ambientais



Descrição geral:

A ideia deste projecto é o desenvolvimento de um protótipo totalmente funcional para uma estação móvel  usada na coleita de dados ambientais tais como: temperatura, humidade e luminosidade.


Considerações do projeto:


  • O Rover será controlado remotamente por um dispositivo Android com capacidade Bluetooth. Os dados serão continuamente capturados e transmitidos independentemente se o Rover está parado ou em movimento.

  • O usuário deve receber um feedback visual (streaming de vídeo ao vivo)

  • Os dados capturados serão analisados através de um site público (neste caso: thingspeak.com)

  • Os dados estarão disponíveis para os usuários em um formato gráfico e tabela

  • Alarmes via Twitter serão gerados localmente pela estação ou pelo website

  • O Rover terá capacidade autónoma para evitar obstáculos a fim de proteger-se em caso de mau controle por parte do usuário.


Opções de projeto:

Com base nos requisitos, inicialmente 2 opções foram consideradas para este projeto.



  1. Um único processador responsável por todas as tarefas, que neste caso deveria ser um Raspberry Pi.

  2. Um processador dual , sendo as funções divididos entre eles ( Arduino e RPI ) :

    • Processor 1: RPi

      • Captura de dados

      • Comunicação com a Web

      • Transmissão de vídeo

      • Envío de mensagens via mídia social



    • Processor 2: Arduino

      • Controle dos motores (movimento e posicionamento da câmera)

      • Evasão de obstáculos

      • Comunicação com o controle remoto






Em termos de custos, utilizar 2 processadores é de fato menos custoso do que a opção de um único processador. Isso ocorre porque o Arduino é um item muito barato e portanto mais acessível que a opção de “Servo Hat”, necessária para o RPi controlar os servos de maneira adequada. Outra diferença é o módulo de BT. Para o Arduino, um módulo barato como o HC – 06 BT 3.0 é suficiente, sendo que o mesmo custa a metade do preço do “BT Dongle” a ser adicionado ao Rpi.  Assim,a opção escolhida foi o projeto com processador dual.


diag Block complete


A Lista de materiais:

BoM


Instalação e testes da Camera (Pi-Cam) no RPi


  1. Instale PIP

    • sudo apt- get install python- pip



  2. Instalar a biblioteca picamera :

    • pip install picamera



  3. Instalar a biblioteca flask Python:

    • sudo pip install flask



  4. Baixar projeto de streaming de vídeo Flask:


  5. Na pasta do projeto editar o arquivo app.py , comente esta linha:

    • #from camera import Camera



  6.  Tirar o comentario da linha:

    • from camera_pi import Camera



  7. Salve o arquivo app.py

  8. Executar ifconfig para descobrir o endereço IP local do seu Raspberry Pi “yourLocalIPaddress ” .

  9. Inicie o servidor Flask executando este comando :

    • python app.py 



  10. Uma mensagem será impressa no monitor:


  11. Abra um navegador e acesse este endereço :

    • ” YourLocalIPaddress ” : 5000




Instalando o sensor de temperatura e humidade: HC-11

DH11-RPiDH11-RPi hw



  1. Em primeiro lugar, obter a Biblioteca do Github :


  2. Instalação da Biblioteca :

    • sudo apt-get update

    • sudo apt- get install build-essential python -dev python- openssl

    • cd / Home / Pi / Adafruit_Python_DHT

    • sudo python setup.py install



  3. Teste o sensor, executando o programa: AdafruitDHT.py no monitor. Entre os parâmetros como : 11 ( sensor DHT11 ) e 4 ( GPIO onde o sensor está ligado )

    • sudo Python AdafruitDHT.py 11 4



  4. O resultado deve ser a temperatura ea humidade lido pelo sensorDH11-RPi monitorEnviando dados para a internet

    Para a configuração básica do sensor DH- 11 com a RPI e envio dos dados à internet , uma grande ajuda foi começar a partir deste tutorial:


    Plotting DHT11 sensor data at ThingSpeak.com using Raspberry Pi


    Passos:



    • A definição de um canal em ThingSpeak.com :ThinkSpeak1

    • Execução do códigoPython para testes:

      • sudo Python temp_hum_test.py

      • NOTA: Todos os códigos fonte estão disponíveis ao final do post.ThinkSpeak2ThinkSpeak3


      • Adicionando o sensor de luz:

        Um tutorial muito bom que serviu de base para esta parte do projeto, pode ser visto aqui:


        Build Your First IOT with a Raspberry Pi, DHT11 sensor, and Thingspeak.


        Um LDR e um capacitor foram conectados a GPIO24 . Basicamante, dependendo da constante de tempo RC, pode-se determinar se há luz (GPIO24 ==> HIGH) ou não (GPIO24 ==> LOW).



        • O Código Python utilizado neste teste:

          • sudo Python iot_temp_hum_light.py




        Adicionando um sensor para a intensidade de luz

        RPi sensors3





    • O passo seguinte foi obter ” dados de intensidade da luz ” e uma vez que eu não tinha um ADC ( conversor analógico-digital ) em mãos , uma boa aproximação foi obtida utilizando-se a técnica de carga/descarga de capacitores (também aqui,  o “truque” é a variação da constante de tempo RC) . O ” Raspberry Pi Cookbook ” nos dá a solução (note que, em vez do potenciômetro no exemplo do livro, se usou um LDR).


      O Código Python utilizado neste teste:



      • sudo Python iot_temp_hum_light_pot.pyRPi sensors4RPi sensors5RPi sensors6


      • Enviando mensagens de alarm via Tweeter

        Uma das características do IOT é interagir automaticamente com as pessoas. Para o envio de mensagens de alarme, um dos requerimentos do projeto, se pode tanto programar o RPI como um servidor web para enviar tweets diretamente ou usar o site ThingSpeak para isso. Claro que neste último caso, apenas serão enviadas mensagens “gatilhadas” por uma condição com base nos dados capturados) .


        Abaixo um exemplo de código Python para o envío de tweets diretamente pelo RPi:









 
from twython import Twython
C_KEY = "xxxxxxxxxxxx"
C_SECRET = "yyyyyyyyy"
A_TOKEN = "zzzzzzzzzzzz"
A_SECRET = "wwwwwwwww"
api = Twython(C_KEY, C_SECRET, A_TOKEN, A_SECRET)
api.update_status(status="IoT Capstone Project - Tweet test")
 

Otweet1bserve que a sua conta do Tweeter deve permitir o envío de um tweet a partir da RPI . Além disso, são necessárias chaves especiais geradas pelo Twitter , a fim de que se possa usar a biblioteca TWYTHON disponível para RPI .


Outra solução simples como explicado anteriormente, é enviar um Twitter diretamente do site. Neste caso, pode ser usado o recurso “React” de ThingSpeak.com .


tweet2


tweet3


Conectando o RPi e ao Arduino via port Serial

O Arduino utilizado foi o NANO que é tão poderoso como a UNO, mas com um ” fator de forma” pequeno .


RPi-Ardu-Serial-test


Para fins de teste, um potenciômetro foi conectado aporta analógica A0 do Arduino e o valor lido, transmitido via Serial ao RPI. No teste, o RPI monitorará os comandos fornecidos por um teclado (conectado diretamente ao port USB ou através de VNC)  e dependendo do comando, ou o valor lido no port A0 será impresso no monitor, ou o LED da porta 13 do Arduino será apagado ou acendido (“toggle ON / OFF”).


RPi-Arduino3



  • Abaixo o código Arduino e Python utilizado nos testes :

    • sudo Python ardu_pi_serial.py




Enviando os dados do Arduino para a Web:

RPi-Arduino1


 


Uma vez que o Arduino está conectado com RPI , dados adicionais capturados por Arduino também pode ser enviada para a Web , em conjunto com outros dados captados pelo DH11 e LDR .


O código Python usado para enviar dados para o site foi mudado para também incluiu os dados capturados pelo Arduino (valor de potenciômetro) .


RPi-Arduino2RPi-Arduino4


RPi-Arduino5


Abaixo o código Arduino e Python utilizado nos testes :



  • sudo iot_temp_hum_pot_ardu.py


Testando os motores do rover:

Arduino2


Neste ponto, o Rover vai começar a ser montado. Eu decidimos desmontar todos os sensores e começar do zero, a “Fase Arduino”. Uma vez que a Rover estiver funcionando corretamente, tanto o RPI e sensores serão remontados sobre o Rover na configuração definitiva.


Para motores, foram utilizados 2 servos contínuos (SM-S4303R). Esses servos girarão a uma velocidade, dependendo da largura de pulso recebido em sua entrada de dados. No caso deste servo, a largura de pulso pode variar de 1.0 ms a 2.0ms (outros servos podem trabalhar com larguras de pulso diferentes).


Arduino3



  • Um pulso de 1.5ms vai posicionar o servo na posição neutra, ou “parado”.

  • Um pulso de 1.0 ms vai faz com que o servo gire a maxima velocidade (cerca de 70 RPM) em uma direção e 2.0ms a toda velocidade na direção oposta.

  • Pulsos entre 1.0 e 1.5ms ou 1.5ms e 2.0ms, gerarão velocidades intermediárias proporcionais.


Arduino4A primeira coisa que deve ser feito, é enviar um pulso 1.5ms para verificar se os motores estão “parados”. Caso não estejam, os servos devem ser ajustados para isso (procure o parafuso amarelo, abaixo do servo). É claro que se o seu servo não possui esse ajuste, tente alterar o valor “1.5ms” até obter o ponto neutro.


Codigo para calibração dos servos:


 


 
#include Servo
leftServo;
Servo rightServo;
Void setup()
{
   leftServo.attach(6);
   rightServo.attach(5);
   leftServo.writeMicroseconds(1500);
   rightServo.writeMicroseconds(1500);
}
void loop()
{
}
 

O código abaixo , pode ser usado para um teste de motor Rover completo (para frente , para trás, parada completa , virar à esquerda , virar à direita ). Se necessário, dependendo de seus motores você deve ajustar os “delays” para obter o ângulo de viragem desejado, (também, por vezes, os valores para a largura do pulso a direito devem ser um pouco diferentes que os da esquerda para compensar qualquer falta de equilíbrio dos motores ou desalinhamento da estrutura do Rover).



  • MotorCode.ino


Montagem da estrutura final do Rover e testes com o Controle Remoto/Bluetooth:

Primeiro de tudo, note que o robô ou ” Rover ” é um protótipo para fins educacionais e foi construído com elástico, madeira e clips de junção das peças originais. É muito simples, mas funciona bem para o que se pretende .


Remote Ctrl5Remote Ctrl3Remote Ctrl4


No Arduino , foi utilizado um módulo Bluetooth HC – 06 . Você precisa de mais informações sobre como usar este módulo, consulte o meu post:


Conectando “coisas” com o Bluetooth


Remote Ctrl1Remote Ctrl2


O código Arduino completo ( o anterior + BT ) estão disponíveis nos arquivos abaixo (não se esqueça que os 3 arquivos , devem estar dentro de uma pasta exclusiva) :



  • Iot_Capstone_Robot_10mar16.ino

  • motorFunctions.ino

  • robotDefines.h


A App Android

Para o controle remoto , um dispositivo Android foi o escolhido , pois é muito fácil de desenvolver um aplicativo usando o MIT AppInverntor2 . Para este projeto, desenvolvi o um aplicativo dedicado .


Andoid blocksAndoid desig1Andoid desig2


 


 


O aplicativo é muito simples. Ele possui:



  • 5 botões para controle de direção ( FW , BW , esquerda, direita , Stop). Quando um desses botões é pressionado, um caracter é enviado via Bluetooth para o HC- 06, sendo o respectivo comando executado pelo Arduino.

  • 1 Slider para o movimento da câmera. Um valor numérico é enviado de 0 a 100. Esse valor será ” mapeado ” no Arduino movendo a câmera proporcionalmente, dependendo da faixa de ângulo Servo (no meu caso algo de 20 a 160 graus )

  • Entrada do endereço IP da PiCam e um botão para armazená-lo.

  • Enviar / receber mensagens de texto para Arduino (o botão ” avião de papel ” é usado para enviar as mensagens)


O arquivo .aia disponível no final do post pode ser utilizado para gerar/modificar seu app caso você esteja familiarizado com o MIT AppInverntor2 e o arquivo .apk caso você deseje instalar e executar o aplicativo que desenvolvi diretamente em seu dispositivo Android.


rover icon


App Android



Os sensores para deteção de obstáculos:

ultrasound sensor2ultrasound sensor1


Para evitar obstáculos, será usado um sensor de ultra-som (HC- SR04 ). O sensor será montado sobre um servo 180o, com o objetivo de aumentar a área a ser pesquisada. Note que o servo também será utilizado como uma base para a Pi – câmera. Um controle deslizante na aplicação Android irá controlar o ângulo da câmera.


O HC-SR04 funciona enviando um pulso sonoro no pino “trigger” ( 2us LOW ; 10us HIGH), medindo quantos microsegundos um pulso refletido leva para retornar ao pino “echo” (lembre-se que o som viaja a 340m/s). A função “int distMeter ()” é utilizado para este cálculo.


No caso de um obstáculo a frente ser encontrado a menos de 20 centímetros, o LED vermelho acenderá e o rover parará, retrocedendo alguns centímetros por segurança. O vídeo mostra os testes com o Rover.


Vídeo de teste de obstáculos


O código completo Arduino (o anterior + desvio de obstáculos e procure servo controle ) está disponível nos arquivos:


http://www.instructables.com/files/orig/FAS/FRME/ILV8FP0N/FASFRMEILV8FP0N.ino


Integração e testes finais:

final circuit


Neste ponto, todas as partes individuais foram testados e funcionam. Agora, chegou a hora do Rpi e do Arduino serem integrados. As etapas a serem executadas nesta etapa são:



  1. Em primeiro lugar, execute o programa python para ativar a Pi- Cam que está no diretório flask e verifique se a camera está enviando o viseo em streaming:

    • sudo python app.py



  2. Uma vez que você pode ver o vídeo, execute um CTRL- C para libertar o monitor para introduzir o código Python principal (O mesmo que o utilizado no passo 11).

    • sudo iot_temp_hum_pot_ardu.py



  3. Verificar os valores dos sensores ( aquecer o sensor , cobrir o sensor de luz , etc. ) . Veja o resultado no monitor e no site :

    • sudo python iot_temp_hum_light_pot_ardu.py



  4. Execute o sketch final para o Arduino.

  5. Mova o rover com o aplicativo Android e confira o vídeo e os valores do sensor

  6. Verifique se o rover para em um obstáculo.

  7. Monitorar o site e veja se os dados ambiente continuamente sido exibidos.


O vídeo mostra o protótipo completo sendo controlado pelo aplicativo Android , capturando dados do sensor e mostrando na Internet.


Video do rover completo 


Abaixo os códigos Finais :


Codigos para o Arduino


Codigos em Python para o RPi


Conclusão:

IMG_3178IMG_3171IMG_3179


No futuro pretendo incluir algumas características adicionais ao projeto:



  • Controlar o Rover pela internet.

  • Adicionar um braço robótico, de modo que o Rover possa fazer algum trabalho mecânico como a remoção de obstáculos, coleta de amostras , etc.

  • Fonte de energia usando painéis solares.FullSizeRender 10

    (Uma opção é usar como base o Rover em MDF projetado pelo Mauricio dos Santos)


    Desta maneira poderia-se realmente simular um “Mars Rover”.


    Logo da publicação deste projeto no site do Instructables.com, fui procurado pela revista inglesa oficial do Raspberry-Pi, a MagPi, para dar uma entrevista e contar de como foi o desenvolvimento do Mars Rover. Foi bem legal! Aqui, um pouco sobre a matéria:


    O Mars Rover Tupiniquim aterrisa em Londres!





11
Projetos / “Rex”, um robot que nunca perde a linha!
« Online: Dezembro 08, 2017, 09:22:13 am »
“Rex”, um robot que nunca perde a linha!



O objetivo deste projeto é construir um robot seguidor de linha com controle PID. Também usaremos um dispositivo Android para poder configurar mais facilmente os principais parâmetros (ganhos) da malha de controle.


INTRODUÇÃO:


Esta é a primeira parte de um projeto mais complexo, explorando a potencialidade de um robô seguidor de linha. Construiremos um robô com controle PID e também aprenderemos como usar um dispositivo Android na configuração mais dos principais parâmetros (ganhos) de sua malha de controle. Na segunda parte deste projeto Robô explorador de labirintos, utilizando Inteligência Artificial com Arduino, aplicaremos conceitos de inteligência artificial para explorar labirintos,  encontrando o caminho da saída mais curto e rápido.


Abaixo um vídeo que mostra o robô seguindo um circuito básico:



LISTA DE MATERIAIS:


A lista de materiais necessários é simples e o preço final do robô, muito barato (cerca de US$ 75,00):



  • Corpo (pode ser adaptado para as suas necessidades):

    • 2 quadrados de madeira (80x80mm)

    • 3 Grampos de papel

    • 2 rodas de madeira (diâmetro: 50 mm)

    • 1 roda “solta” (Caster)

    • 9 Elásticos

    • Fita 3M “Command”

    • Articulações plásticas para fixação do sensor



  • Protoboard e fiação

  • 2 conjuntos de baterias (4XNi-metal hidreto) –  5V cada conjunto

  • 2 Servos de Rotação Contínua (SM-S4303R)

  • Arduino Nano

  • Módulo Bluetooth  HC-06

  • 5 sensores x Linha (TCRT5000 4CH Infrared Linha Pista Seguidor Módulo Sensor + 1 sensor de Pista independente)

  • 1 LED

  • 1 Botão


AJUSTE DOS MOTORES


Como motores, utilizei 2 servos em modo contínuo (SM-S4303R). Eles devem ser “colados”, formando um único e sólido bloco como você pode ver na foto (use a fita 3M Command, cola ou fita dupla face). Esses servos girarão a uma dada velocidade dependendo da largura do pulso que receba em sua entrada de dados. Para este servo específico, a largura do pulso varia de 1.0 ms a 2.0ms (outros tipos de servos podem trabalhar com larguras de pulso diferentes).


Arduino3


Olhando em detalhes:



  • Um pulso de 1.5ms comandará o servo para que fique em sua posição neutra, ou “parado”.

  • Um pulso de 1.0 ms comandará o servo para que funcione em sua velocidade máxima (cerca de 70 RPM) em uma direção e 2.0ms na direção oposta.

  • Pulsos entre 1.0 e 1.5ms ou 1.5ms e 2.0ms, farão os servos girarem em velocidades intermediárias e proporcionais.


Arduino4


 


A primeira coisa que se deve fazer, é enviar um pulso de 1.5ms (1500us) para verificar se os motores ficam realmente”parados”. Caso isto não ocorra, os servosdevem ser ajustados (procure o parafuso amarelo, na lateral do servo). É claro que se o seu servo não possui esse ajuste, tente alterar o valor “1500ms” até obter o ponto final.


Monte o Arduino e os servos como mostrado abaixo:


Motorflb5wsqin3edek6-large


O código abaixo, para o Arduino deve ser usado para o ajuste:


 
#include Servo // este código linha deve ser mudado, por favor, olhe o código anexado
Servo leftServo;
Servo rightServo;
void setup ()
{
   leftServo.attach (5);
   rightServo.attach (3);
   leftServo.writeMicroseconds (1500);
   rightServo.writeMicroseconds (1500);
}

void loop ()
{
}
 

MONTAGEM DO CORPO E MOTORES PARA TESTE DE MOVIMENTO


fk1e3mein3ef60l-medium


 


1. Com a fita 3M Command, fixar os 2 Servos à uma das peças de madeira quadrado.


 


 


fd75kabin3ef63f-small


 


2. Fixar o segundo quadrado de madeira ao anterior, utilizando os grampos de papel. Ajuste o comprimento da plataforma para suas necessidades.


fb16lqlin3ef65n-small


 


 


 


 


 


 


 


3. Fixe o caster utilizando-se o grampo de papel.


 


4. A alimentação para os motores será fornecida por um dos conjuntos de baterias (5V). Este conjunto de baterias será instalado entre o protoboard e a plataforma do corpo.


 


 


fog5h6ein3ee14w-small

5. Conecte a bateria a ser utilizada com os servos: deixe uma linha de alimentação lateral do protoboard exclusivamente para os servos


6. Conecte o Arduino Nano ao protoboard


7. Conecte os terras do Protoboard ao GND do Arduino.


8. Conecte os Servos ao Arduino: LEFT => Pin 5;   RIGHT => Pin 3


9. Ligue o LED ao Arduino Pino 13


10. Ligue o botão para Arduino Pin 9


 


Note que, devido a maneira com que os servos estão montados (em oposição) as faixa de variação de velocidade em função da largura de pulso são diferentes:



  • RIGHT Servo: velocidade de avanço frontal vai de 1500us (parado) a 2000us (velocidade máxima)

  • LEFT Servo: velocidade de avanço frontal vai de 1500us (parado) a 1000us (velocidade máxima)


Um LED externo é adicionar ao pin13, com finalidade de sinalização e testes (você pode usar o LED interno do Arduino se quiser, mas leve em consideração que será difícil de vê-lo no meio dos cabos).


Além disso, um botão é ligado ao pino 9. Este botão será muito útil para testes e para o comando de início, quando o robô estiver posicionado no início do circuito de linha.

Por exemplo:


 
while (digitalRead (buttonPin)) {}
    motorTurn (LEFT, 500);
    motorTurn (RIGHT, 500);
 

Note que as 2 linhas que irão comandar o robô para virar à esquerda, esperar 500ms e virar à direita, só serão executadas depois que você pressionar o botão (buttonPin = 0). Antes disso, o programa ficará executando um “loop infinito”.


O código Motor_Test.ino, disponível no final deste tutorial, poderá ser usado como uma base para um teste de motores mais completo (para frente, para trás, parada completa, virar à esquerda, virar à direita). Se necessário você deverá ajustar os atrasos (“delays”) para obter um ângulo de virada correto.. Também, dependendo de seus motores, os valores definidos para a largura de pulso devem ser um pouco diferentes para compensar qualquer falta de alinhamento entre os mesmos.


INSTALANDO O MÓDULO BLUETOOTH (OPCIONAL)


O módulo Bluetooth HC-06 deverá ser instalado no protoboard. A biblioteca SoftSerial do Arduino será utilizada.


Motor&BTf4fe9iqin3eedct-medium


Abaixo as conexões de pino HC-06:


Tx Pin para Arduino pino 10 (Rx)

RX Pin para Arduino pino 11 (Tx)

VCC / GND para Arduino 5V / GND


O robô funcionará com ou sem o módulo Bluetooth. O código será construído de uma maneira que caso você não ative o BT, os parâmetros utilizados serão os padrões. Na última parte deste tutorial, vou explorar como usar um aplicativo Android para enviar dados para um melhor ajuste dos parâmetros do robô e mover-lo em modo manual. O uso da App Android é um opcional no caso que alguém deseje explorar mais o uso de um Robô seguidor de linha em competições, por exemplo.


ADICIONANDO OS SENSORES DE LINHA


fqq0sfhin3ees26-large


1. Fixe os 5 sensores em uma barra de plástico, como mostrado nas fotos


 


 


fw9zenoin3eeqyx-large


2. É aconselhável para rotular os sensores para fins de teste. O nome sensores vai de de “0” (mais à esquerda) para “4” (mais à direita)


 


f9d55psin3eer0w-large


3. Passe os cabos sob o quadro, usando os elásticos para corrigi-los (tome cuidado para não misturar-se com as rodas ou Caster.


 


f5c3vfgin3eersy-large


4. Conecte os cabos de pinos do Arduino, como abaixo:



  • Sensor 0 = 12

  • Sensor 1 = 18

  • Sensor 2 = 17

  • Sensor 3 = 16

  • Sensor 4 = 19


fmhzshlin3ecx2e-large


 


5. Fixe o segundo conjunto de baterias 5V e conecte ao pino Vin do Arduino.


Line Follow full circuit


 


 


 


Em meu caso, estou usando um módulo com 4 sensores integrados + 1 extra. Todos são compatíveis. Para simplificar, no diagrama abaixo, I inclui 5 sensores individuais conectados juntos. O resultado final é o mesmo em ambas as configurações.


 


 


 


 


 


IMPLEMENTANDO A LÓGICA DOS SENSORES DE LINHA


IRsensorCada sensor é constituído por um LED e um fotodiodo, ambos infravermelhos. A luz emitida pelo LED atinge a superfície e é reflectida de volta para o fotodiodo. O fotodiodo em seguida, gera uma tensão de saída proporcional à reflectância da superfície.


Track SensorsNo caso dos sensores utilizados, um circuito integrado no módulo gera um sinal de saída digital simples (ALTO: escuro; BAIXO: Luz). Um potenciômetro instalado no módulo (ver foto) irá ajustar o nível correto de luz para ser considerada “dark” ou não. Quando a luz reflectida é conLine Follower Sensorsiderada “escura”, a saída fica ALTA ( “1”) e BAIXA ( “0”) para outra cor mais clara. Eu usei aqui um módulo integrado com 4 sensores e e módulo extra com um sensor único (forma diferente, mas mesma lógica). A combinação é uma matriz de 5 sensores que eu considero apropriado para este tipo de controle, como explicado abaixo.


Sensor1_Cover


A matriz de 5 sensores  é montada de forma que, se apenas um sensor está centrado em relação à linha preta, ele irá produzir um “1”.


 


Sensor1_&amp;2_Cover


Por outro lado, o espaço entre os sensores devem ser calculados para permitir que 2 sensores possam cobrir a largura total da linha preta simultaneamente,também produzindo assim um “1” em ambos os sensores (ver os quadros aqui).

As possíveis combinações de saída do conjunto de sensores são:



  • 0 0 0 0 1

  • 0 0 0 1 1

  • 0 0 0 1 0

  • 0 0 1 1 0

  • 0 0 1 0 0

  • 0 1 1 0 0

  • 0 1 0 0 0

  • 1 1 0 0 0

  • 1 0 0 0 0


Trabalhar com 5 sensores, permite a geração de uma “variável de erro” que ajudará a controlar a posição do robô sobre a linha, como mostrado abaixo:

Vamos considerar que a condição ideal é quando o robô está centrado, tendo a linha apenas abaixo do “sensor do meio” (Sensor 2). A saída da matriz será: 0 0 1 0 0  e nesta situação, o “erro” será “zero”.


Se o robô começa a derivar para a esquerda (a linha “parece mover-se” para a direita) o erro deverá aumentar e com um sinal positivo. Se o robô começar a mover-se para a direita (a linha” parece mover-se “para a esquerda), da mesma maneira, o erro tem de aumentar, mas agora com um sinal negativo.

A variável de erro, relacionada com o estado do sensor será:



  • 0 0 0 0 1 ==> erro = 4

  • 0 0 0 1 1 ==> erro = 3

  • 0 0 0 1 0 ==> erro = 2

  • 0 0 1 1 0 ==> erro = 1

  • 0 0 1 0 0 ==> erro = 0

  • 0 1 1 0 0 ==> erro = -1

  • 0 1 0 0 0 ==> erro = -2

  • 1 1 0 0 0 ==> erro = -3

  • 1 0 0 0 0 ==> erro = -4


Olhando o código Arduino, cada um dos sensores será definido com um nome específico (considere que o Sensor mais à esquerda deve ser atribuído com uma etiqueta de “0”):


 
const int lineFollowSensor0 = 12;
const int lineFollowSensor1 = 18;
const int lineFollowSensor2 = 17;
const int lineFollowSensor3 = 16;
const int lineFollowSensor4 = 19;
 

A fim de armazenar os valores de cada um dos sensores uma variável tipo Array será criada:


 
int LFSensor [5] = {0, 0, 0, 0, 0};
 

Cada posição da matriz irá ser constantemente actualizada com a saída de cada um dos sensores:


 
LFSensor [0] = digitalRead (lineFollowSensor0);
LFSensor [1] = digitalRead (lineFollowSensor1);
LFSensor [2] = digitalRead (lineFollowSensor2);
LFSensor [3] = digitalRead (lineFollowSensor3);
LFSensor [4] = digitalRead (lineFollowSensor4);
 

Uma vez armazenado o valor de cada um dos sensores, uma lógica deve ser implementada para gerar a variável de erro:


 
if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 1 )) erro = 4;
else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 1) && (LFSensor [4] == 1)) erro = 3;
else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 1) && (LFSensor [4] == 0)) erro = 2;
else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 1) && (LFSensor [3] == 1) && (LFSensor [4] == 0)) erro = 1;
else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 1) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = 0;
else if ((LFSensor [0] == 0) && (LFSensor [1] == 1) && (LFSensor [2] == 1) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = - 1;
else if ((LFSensor [0] == 0) && (LFSensor [1] == 1) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = -2;
else if ((LFSensor [0] == 1) && (LFSensor [1] == 1) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = -3;
else if ((LFSensor [0] == 1) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = -4;
 

CONTROLANDO A DIREÇÃO (PROPORCIONAL CONTROL – P)


Perfeito! Neste ponto, o robô está montado e operacional. Você deve aproveitar e executar alguns testes básicos com os motores, ler a saída de sensores e testá-los através de uma linha. O que está faltando ainda, é o verdadeiro “cérebro”, ou seja fazer o Robô executar a tarefa de “andar na linha” por seus próprios meios. Vamos conseguir isso, através da implementação de uma lógica de controle que garantirá ao robô seguir uma linha, seja qual for o desenho.


PD Control


Suponha que o robô esteja “andando” sobre uma linha e a saída do Array de Sensores é: “0 0 1 0 0”.  Neste caso, o erro correspondente é “0” e ambos os motores estarão empurrando o robô para a frente com uma velocidade constante. Um código para essa condição seria:


 
rightServo.writeMicroseconds (1500 + iniMotorPower);
leftServo.writeMicroseconds (1500 - iniMotorPower);
 

Por exemplo, com iniMotorSpeed = 250, significa que LEFT Servo receberá pulsos de 1,1250us e o RIGHT Servo 1750us, o que fará com que o robô avance com metade de sua velocidade máxima. Lembre-se que a velocidade de avanço do Servo direito irá variar com larguras de pulso que variam de 1500us (parado) a 2000us (velocidade máxima) e o Servo esquerdo de 1500us (parado) a 1000us (velocidade máxima).


Suponha agora que o robô comece a derivar para a esquerda ( a “linha vai para a direita”), fazendo com que o sensor 3 també, fique sobre a linha. Neste caso, a saída do Array de sensores será: “0 0 1 1 0” e o erro = 1. Nesta situação, o que necessitamos é virar o robô para a direita. Para fazer isso, devemos diminuir a velocidade do Servo direito o que significa diminuir a largura do pulso. Além disso, a velocidade do Servo esquerdo deve aumentar, o que significa diminuir a largura do pulso. Para isso, precisamos alterar a função de controle do motor:


 
rightServo.writeMicroseconds (1500 + iniMotorPower - erro);  // Erro positivo: velocidade diminue
leftServo.writeMicroseconds (1500 - iniMotorPower - erro);  //Erro positivo: velocidade aumenta
 

A lógica acima é correcta, mas é facil compreender que a adição ou subtracção de apenas “1” microssegundo na duração dos pulsos não irá gerar a correcção necessária, ao menos em um tempo realista. É intuitivo que o número a se adicionar ou subtrair deve ser maior, por exemplo, 50, 100, etc. Para conseguir isso, o “erro” deve ser multiplicado por uma constante “K”. Uma vez que a influência dessa constante será proporcional ao erro, vamos chamar-la “Constante proporcional: Kp. No meu caso, testei o robô com uma constante Kp=50 e ele funcionou muito bem.


A função final para os motores será:


 
int Kp = 50;
rightServo.writeMicroseconds (1500 + iniMotorPower - Kp * erro);
leftServo.writeMicroseconds (1500 - iniMotorPower - Kp * erro);
 

Podemos resumir o que acontecerá com os motores, como mostrado abaixo:



  • Array de Sensores: 0 0 1 0 0

    • erro = 0

    • Servo direito: pulso = 1750us

    • Servo esquerdo: pulso  = 1250us

    • (ambos os motores a mesma velocidade)



  • Array de Sensores: 0 0 1 1 0

    • erro = 1

    • Servo direito: pulso = 1700us (mais lento)

    • Servo esquerdo: pulso = 1200us (mais rápido)




Se a situação é o oposto e o robô vai para a direita, o erro seria “negativo” e a velocidade dos servos deve mudar:



  • Array de Sensores: 0 0 1 0 0

    • erro = 0

    • Servo direito: pulso = 1750us

    • Servo esquerdo: pulso = 1250us

    • (ambos os motores a mesma velocidade)



  • Array de Sensores: 0 1 1 0 0

    • erro = -1

    • Servo direito: pulso = 1800us (mais rápido)

    • Servo esquerdo: pulso = 1300us (mais lento)




Neste ponto fica claro que quanto mais o robô “escorregue” para um lado, maior será o erro (1, 2, 3 ou 4) e mais rápido ele deve retornar ao centro (valores a serem adicionados a largura do pulso: 50, 100, 150, 200). A velocidade com que o robô irá reagir ao erro será proporcional ao mesmo.


CONTROLE PID


Controle PID (Proporcional, Derivativo e Integral) é um dos sistemas de controle mais comuns que existem. A maioria dos sistemas de controle industriais utilizam algum tipo do controle PID. Há muitas maneiras de ajustar uma malha PID, incluindo a técnica “tentativa e erro”, que é a que usaremos nesse projeto.


Pense no PID como uma mola simples. Uma mola tem um comprimento original (setpoint), que quando perturbada, pela expansão ou contração, tende a recuperar o seu comprimento original no menor tempo possível. Controladores PID são utilizados onde quer que haja a necessidade de controlar uma quantidade física e a torná-la igual a um valor pré-especificado. Por exemplo, controlador de velocidade em carros, robôs, reguladores de temperatura, reguladores de tensão, etc.


Como o PID funciona?

O sistema calcula o “ePIDrro” ou “desvio” da quantidade física em relação ao set point, medindo o valor atual dessa quantidade física usando um sensor. Para voltar ao set point, este “erro” deve ser minimizado, idealmente igual a zero. Além disso, esse processo deve ocorrer o mais rapidamente possível (também idealmente esse tempo deveria ser zero).

Mais informações, acesse:  http://en.wikipedia.org/wiki/PID_controller


Implementando PID



  1. erro (e):

    Este valor é igual à diferença entre o ponto de regulação e o valor actual da quantidade a ser controlada.

    error = set_point – CURRENT_VALUE (no nosso caso é a variável de erro começa a partir da posição do robô sobre a linha

  2. Termo Proporcional (P):

    Este termo é proporcional ao erro.

    P = error

    Este valor é responsável pela magnitude da mudança necessária na quantidade física para atingir o ponto de ajuste. O termo proporcional é o que determina o tempo de subida da malha de controle ou o quão rápido ele vai chegar ao set point.

  3. Termo Integral (I):

    Este termo é a soma de todos os valores de erro anterior.

    I = I + error

    Este valor é o responsável pela rapidez de resposta do sistema para a mudança do ponto de ajuste. O termo integral é utilizado para eliminar o erro de estado estacionário exigido pelo termo proporcional. Normalmente, pequenos robôs não usam o termo integral porque não estamos preocupados com erro de estado estacionário e isso pode complicar o ajuste.

  4. Diferencial ou termo derivativo (D):

    Este termo é a diferença entre o erro instantâneo do ponto de ajuste, e o erro a partir do instante anterior.

    D = error – previousError

    Este valor é responsável para diminuir (“slow down”) a taxa de variação da quantidade física quando nos aproximamos do ponto de ajuste. O termo derivativo é utilizado a reduzir o “overshoot” ou o quanto o sistema “super corrige”.


Equação:


 
PIDvalue = (Kp * P) + (Ki * I) + (Kd * D)
 

Onde:


Kp é a constante usada para fazer variar a magnitude da mudança necessária para atingir o ponto de ajuste.

Ki é a constante utilizada para variar a velocidade com que a mudança deve ser apresentado na quantidade física para atingir o ponto de ajuste.

Kd é a constante utilizada para variar a estabilidade do sistema.

Uma abordagem para a obtenção das constantes é deixar Ki de fora e trabalhar com o Controle PD (manter Ki = 0); definir a variável Kd como 0 e sintonizar o termo Kp sozinho pela primeira vez. Kp de 25 é um bom lugar para começar no nosso caso aqui e ir subindo seu valor. Na última etapa foi utilizado um Kp de 50 que funciona muito bem com meu robô. Se o robô reagir muito lentamente, voce deve aumentar o valor. Se o robô parece reagir muito rapidamente tornando-se instável, diminua o valor. Uma vez que o robô responda razoavelmente, sintonize a parte derivativa da malha de controle. Primeiro defina o valor Kp e Kd cada um para a 1/2 do valor Kp. Por exemplo, se a resposta do robô é razoável com um Kp = 50, definir Kp = 25 e Kd = 25 para iniciar. Aumente o ganho de Kd para diminuir o “overshoot ou o diminua se o robô se tornar instável.


Um outro componente do loop a ser considerado é a taxa real de amostra / loop. Acelerar-la ou para retardar-la pode fazer uma diferença significativa no desempenho do robô. Isso é definido pelas declarações de “Delay” que você tem em seu código. Use o método tentativa-erro para obter o melhor resultado.


Com base na abordagem anterior, implementamos a função abaixo:


 
void calculatePID ()
{
   P = error;
   I = I + error;
   D = error - previousError;
   PIDvalue = (Kp * P) + (Ki * I) + (Kd * D);
   previousError = error;
}
 

A constante Kp simples usada na última etapa será substituída agora por PIDvalue, mais completa:


 
void motorPIDcontrol ()
{
   int leftMotorSpeed = 1500 - iniMotorPower - PIDvalue;
   int rightMotorSpeed = 1500 + iniMotorPower - PIDvalue;
   leftServo.writeMicroseconds (leftMotorSpeed);
   rightServo.writeMicroseconds (rightMotorSpeed);
}
 

Mas note que se você tem Kd e Ki = 0, PIDvalue = Kp * error, exatamente como na etapa anterior onde usamos só o controle Proporcional.


ADICIONANDO CONDIÇÕES ESPECIAIS AO CÓDIGO FINAL


FullSizeRender 13


Neste ponto do projeto, o robô já pode seguir sem parar um circuito de linha do tipo “loop constante”.


A função Loop do programa de ciclo seria simplesmente:


 
void loop ()
{
   readLFSsensors (); // Ler sensores, armazenar os valores no Array de sensores e calcular o "erro"
   calculatePID ();
   motorPIDcontrol ();
}
 

Mas, para uma operação mais completa e real, é importante acrescentar, pelo menos um par de “comandos básicos de linha”.


 
Por exemplo, vamos introduzir uma nova variável: "mode", definindo 3 estados para esta variável:

#define STOPPED 0
#define FOLLOWING_LINE 1
#define NO_LINE 2
 

Se todos os sensores de encontrar uma linha preta, a saída do Array de Sensor seria: 1 1 1 1 1. Nesta condição, podemos definir o modo como “PARADO” e o robô deve realizar um “Full Stop”.


 
if ((LFSensor [0] == 1) && (LFSensor [1] == 1) && (LFSensor [2] == 1) && (LFSensor [3] == 1) && (LFSensor [4] == 1 )) {mode = STOPPED;}
 

Outra situação comum com robôs seguidores de linha, é quando o mesmo não encontra “nenhuma linha”, ou a saída do Array de Sensores é: 0 0 0 0 0. Neste caso, podemos programá-lo para girar 180 graus (ou girar em ângulos pequenos até que uma linha é encontrada e a condição normal FOLLOWING_LINE é retomada.


 
else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) {mode = NO_LINE;)
 

A função loop completa seria:


 
void loop ()
{
   readLFSsensors ();
   switch (mode)
   {
     case STOPPED:
        motorStop();
        break;
     case NO_LINE:
        motorStop ();
        motorTurn (LEFT, 180);
        break;
     case FOLLOWING_LINE:
        calculatePID ();
        motorPIDcontrol ();
        break;
   }
}
 

O código final incluirá integrar lógica adicional e também algumas variáveis devem ser inicializadas, etc. Durante as explicações , deixei estes detalhes de fora para simplificar a explicação, mas acredito que tudo fique claro dando uma olhada no código final.


USANDO O APP ANDROID PARA AJUSTAR OS GANHOS DO CONTROLADOR PID


No código do Arduino, você poderá encontrar no arquivo “robotDefines.h” as seguintes definições para as constantes “default” serem usadas com o controle PID.


 
float Kp = 50;
float Ki = 0;
float Kd = 0;
 

Como explicado anteriormente,  a melhor maneira de definir os ganhos corretos (Constantes Kd, Ki e Kd) é usar a metodologia “Tentativa-e-erro”. O lado ruim disso é que você deve re-compilar o programa a cada vez que você defina uma constante nova. Uma maneira de acelerar o processo é usar o App Android para enviar as constantes na fase de setup do programa.


Picture1


Eu desenvolvi um aplicativo Android exclusivamente para isso:


o MJRoBot Line Follower PID Control


Em resumo o aplicativo possui:


fkhjj4uin699t7j-medium



  • Comandos manuais tradicionais:

    • FW, BW, esquerda, direita e parar onde o aplicativo irá enviar ao módulo BT HC-o6, respectivamente:  ‘f’, ‘b’, ‘l’, ‘r’ e ‘s’.




 


fpjpy8zin699t7l-medium



  •  3sliders , um para cada constantes PID:

    • Kp: “p / XXX”

    • Ki: “i / XXX”

    • Kd: “d / XXX”

      • Em que “XXX” é um número de 0 a 100.






 


 



  • Um botão extra (“Play”) que funciona exatamente como o botão conectado ao pino 9 do Arduino. Você poderá utilizar um ou o outro, não importa.


No final deste tutorial, você encontrará o arquivo .aia que pode ser modificado no MIT AppInventor e o arquivo .apk para ser instalado diretamente no seu dispositivo Android.



  • MJRoBot_Line_Follower_PID_Control.aia

  • MJRoBot_Line_Follower_PID_Control.apk


ALTERAR O CÓDIGO PARA O AJUSTE REMOTO DOS GANHOS DO PID


Durante a fase de setup do programa, introduziremos um “loop” onde você poderá enviar os parâmetros PID para o robô antes de colocá-lo sobre a linha:


 
while (digitalRead (buttonPin) && !mode)
{
   checkBTcmd (); // Verificar se um comando é recebido via controle remoto BT
   manualCmd (); // Executar o comando
   command = "";
}
checkPIDvalues (); // Enviar as constantes PID para o dispositivo Android (apenas para verificação)
mode = STOPPED;


A função de comando manual, será:


 
void manualCmd ()
{
   switch (command [0])
   {
      case "g":
        mode = FOLLOWING_LINE;
        break;
      case "s":
        motorStop (); // Desligar ambos motores
        break;
      case "f":
        motorForward ();
        break;
      case "r":
        motorTurn (RIGHT, 30);
        motorStop ();
        break;
      case "l":
        motorTurn (LEFT, 30);
        motorStop ();
        break;
      case "b":
        motorBackward ();
        break;
      case "p":
        Kp = command [2];
        break;
      case "i":
        Ki = command [2];
        break;
      case "d":
        Kd = command [2];
        break;
    }
}
 

No vídeo, você poderá ver alguns testes usando o App Android:


Video Robot seguidor de linha


Abaixo o código final para o robot:


ARDUINO & ANDROID CODES



12
Projetos / Classificar o carrinho de controle remoto
« Online: Dezembro 08, 2017, 09:21:38 am »
[html]Classificar o carrinho de controle remoto


         
      

Neste projeto, vamos desarmar um carrinho de controle remoto, substituindo a sua eletrónica por um microprocessador Arduino controlado por dispositivo Android.


Sempre que passo em uma loja de brinquedos e vejo carrinhos de controle remoto na vitrine, fico doido para levar-los para casa, deve ser porque tinha adoração por este tipo de brinquedo, mas por falta de opções e grana, não cheguei a ter um quando criança. Para compensar e ter uma desculpa para comprar um


13
Projetos / Os relés de estado sólido
« Online: Dezembro 08, 2017, 09:20:15 am »
Os relés de estado sólido




  • Introduzir alguns conceitos de corrente alternativa AC.

  • Apresentar os tiristores e TRIACs.

  • Conhecer os relés de estado solido ou SSR..

  • Utilizá-los para comutar una lâmpada doméstica de 220 VAC


MATERIAL REQUERIDO


Arduino UNO ou equivalente


 


Um relé de estado sólido ou SSR


 


CONTROLAR A CORRENTE ALTERNATIVA AC


Toda a nossa civilização se baseia na eletricidade alternativa e confia nela para transmitir energia barata e instantânea.


Reparamos que é possível comutar corrente alternativa com um relé normal, mecânico, por isso é razoável perguntarmos porque é que há mais tipos de relés.


O motivo é porque estes relés abrem toda uma nova gama de aplicações em regulação de potência no mundo de corrente alternativa (Que é a única que conta quando falamos de potência).


Na eletrónica industrial, o conceito de controlo de potência por regulação de fase mediante tiristores e TRIACs é a base de tudo.


O controlo da corrente alternativa, tanto monofásica como trifásica e especialmente dos motores, tem muito a ver com os tiristores, TRIACs e Relés de estado sólido.


Porque, ainda que a maior parte dos Arduineiros trabalharam toda a vida em baixa potência sem nenhum risco de receber um choque elétrico, há ocasiões em que o controlo da corrente alternativa é muito interessante, como por exemplo para desenhar um dimmer efetivo de luzes de AC ou regular a velocidade de um motorzito de AC.


TIRISTORES E TRIACS


Um relé pode comutar com facilidade 100 amperios. Basta fazer os contacto móveis mais largos e grossos para que possam transmitir semelhante intensidade, ainda que um relé assim não vai comutar com um agradável clic, mas com um golpe que o fará agitar os molares.


É aqui que reside a sua primeira debilidade. Um relé é mecânico e cada vez que comuta, faz um contacto metálico e por isso o desgaste é o seu maior inimigo. E quanto maior é o relé, mais rápido se estraga.


O outro problema é a velocidade de comutação. Um transistor pode comutar milhões de vezes por segundo mas um relé muito poucas por mais rápido que seja. E quanto maior, mais lento.


Um transistor é uma boa solução mas só a muito baixa potência. Não sofre desgaste mecânico porque não há partes móveis e por isso é muito rápido a comutar, mas a sua capacidade de transmitir alta intensidade é muito limitada.


 



Este é o seu símbolo, e decerto dará conta que parece, de uma maneira suspeita, com o símbolo de um diodo com uma patinha nova GATE ou porta.


Sem entrar em detalhes de construção, digamos que um tiristor é similar a um diodo, porque é um semicondutor que conduz numa única direção, mas com um interruptor ou Gate, que permite ou cortar essa condução e além disso, dispõe da velocidade do transistor na comutação da porta e pode-se construir em todos os ranks de intensidade que um engenheiro queira desejar.


Isso só acontece porque os tiristores são quase o sistema perfeito para controlar a potência que entregamos a, digamos um motor, mas lembre-se que a corrente alternativa comercial não tem um valor constante como a contínua, mas vai variando a sua amplitude através de um ciclo sinodal completo:



Os valores da tensão crescem e decrescem de uma forma regular através do tempo com valores positivos e depois com valores negativos. As companhias elétricas fornecem este tipo de corrente com frequências de 50 Hz e 220 VAC na Europa e 60Hz e 125VAC na América.


Há muita gente que não compreende porque se faz uma coisa tão complicada de forma geral, mas tem que entender que a tensão AC é muito eficaz para transmitir energia que a contínua, especialmente quando é trifásica e além disso perde menos energia que as linhas de transporte, entre outras muitas vantagens.


 


Mas, claro está, dissemos que um tiristor apenas conduz a corrente numa direção, como um diodo, por isso, quando a porta está ativada, o resultado de passa a corrente de cima por um tiristor seria mais ou menos assim:



Porque facilmente cortaria toda a corrente negativa sem mais, como faria um diodo. Por isso quando queremos usá-lo em corrente alternativa em vez dos tiristores, usam-se TRIACs, cujo símbolo é este:



A partir da imagem, pode perceber que é basicamente como dois tiristores em oposição, de modo que quando um se corta, o outro conduz e viceversa e encontramo-nos com um bonito componente, que conduz em ambas direções e que se governa com uma única porta.


É um componente com a velocidade dos semicondutores e a capacidade dos relés, o que faz com que se vendam como rosquilhas.


RELÉS DE ESTADO SOLIDO OU SSRS


Agora já podemos apresentar os relés de estado sólido. Basicamente existem versões de corrente continua e alternativa.


No primeiro caso utilizar transistores de potência internos e no caso dos SSR para AC frequentemente incorporara TRIACS mais um acoplador opto que garante o isolamento galvánico do sistema de controlo na Porta, com respeito ao sistema TRIAC pelo que fluem tensões e correntes elevadas.




  • Como sempre com AC, lembre-se que o cemitério está cheio de otimistas e que não combina com muitas piadas com TRIACs e corrente alternada até você que não tem certeza que você faz.

  • 220V não é um fluxo perigoso se existem diferenciais de segurança adequadas


Por isso é relativamente fácil encontrar no mercado Relés de estado sólido simples e baratos muito fáceis de incluir em nossos projetos quando são necessários, que se manejam de forma igual a um relé mecânico, mas com a enorme virtude de comutar com a rapidez de um transistor e que podemos usar como base para qualquer aplicação que requira governar corrente alternativa.




É um pack de 2 SSRs opto acoplados que podem manejar tanto tensões de até 220VAC como Continua e manejar até 2 Amperios. Controla-se de maneira exatemente igual que um relé mecânico através de uma montagem simples com o Arduino que pode controlá-lo diretamente a partir de um pino qualquer de 5V.


As ligações são triviais e simplesmente necessita de ligar tensão 5V e GND para alimentar os acoples óticos e depois manejam o disparo dos relés com um pino cada um:


 



Podemos usar um programa simples de blinking LED, para conseguir o on e off de uma lâmpada doméstica normal e corrente:


 
void setup()
   {  pinMode (6, OUTPUT) ; }

void loop()
   {  digitalWrite(6, HIGH) ;
      delay (500) ;
      digitalWrite(6, LOW);
      delay(500);
   }
 

O resultado é o que vai ver neste vídeo em espanhol:



Até aqui tudo normal e nenhuma novidade que não se possa fazer com um relé mecânico….mas de certeza que lhe ocorreu uma suspeita.


Se estes relés são tão rápidos como os transistores.. Não poderiamos dar um sinal de PWM ao controlo do SSR? Se com um sinal PWM podiamos regular a tensão eficaz que entregavamos a um motor de continua e variar a sua velocidade…Poderia fazer um atenuador de luz ou dimmer para uma lâmpada de tensão AC?


Poderia usar um programa como este: Prog_164_2


 
#include <Servo.h>      // Incluir a livraria Servo
Servo servo1;         // Criar um objeto tipo Servo chamado servo1
int angulo = 0 ;

void setup()
   {   servo1.attach(6) ;        // Conectar servo1 ao pino 6 }

void loop()
   { for(angulo  = 0; angulo  <= 180; angulo += 1) { servo1.write(angulo); delay(25); } for(angulo = 180; angulo >=0; angulo  -=1 )  
         { servo1.write( angulo );
           delay(25);
         }
   }
 

Não se confunda por usar a livraria servo. Tudo que faz é fornecer uma largura de impulso de sinal modulado no pino seleccionado e o mesmo é válido tanto para um servo como para um motor de corrente contínua.


Este vídeo mostra o que ocorre.



É outros desses exemplos nos quais uma boa ideia acaba sendo um desastre.


O motivo é que a frequência da corrente de 50Hz e a frequência de base do sinal PWM, não estão sincronizadas e isso faz com que a sua interação não seja estável sem flutuante e por isso o resultado é um pequeno desastre, muito longe das nossas intenções.


Para conseguir um atenuador ou dimmer de AC, vamos precissar de sincronizar a corrente AC e o sinal da porta do nosso SSR, lembre-se que é um TRIAC opto acoplado, de modo que possamos cortar ou permitir a condução no mesmo ponto ou fase da senoide alternativa quando nos chega e faze-lo 50 vezes por segundo na Europa e 60 vezes por segundo em América.


Para nós, fazer algo 50 vezes por segundo parece demasiado rápido, mas para os nossos Arduino e SSRs isso é um prazo larguíssimo e precisamos de detetar os passos por zero da senoide de AC e disparar o corte de tensão através da porta…um pouco mais adiante do cruzamento por zero.


 


Compreendo que agora isto pareça um pouco estranho ou até um pouco incompreensível, porque para isto vamos precisar de um par de voltas previas teóricas que os permita compreender a fundo o processo.



14
Projetos / Matriz LED de 8×8 com Arduino e MAX7219
« Online: Dezembro 08, 2017, 09:20:01 am »
Matriz LED de 8×8 com Arduino e MAX7219



Neste tutorial, vamos aprender a controlar as matrices LED de 8×8 com Arduino, em concreto vamos usar os módulos que levam o driver MAX7219, e para controlá-los vamos usar um par de livrarias muito úteis que nos vão facilitar muito o trabalho.


O que faremos será mostrar um texto em scroll usando uma das livrarias, e a outra livraria vamos usar para mostrar um desenho ou um personagem que vamos desenhar nós mesmos. No final do tutorial, vai ver um link para descarregar uma aplicação desenhada para criar padrões (desenhos) para estas matrices de LEDs fizemos nós e é grátis.


Componentes necessários para o projeto


Para o desenvolvimento deste tutorial vamos precisar dos seguintes componentes:



  • 1x Arduino UNO

  • 2x Matriz LED de 8×8 MAX7219

  • 10x Cabos para protoboard



Ligação dos módulos


Matrices LED con Arduino y MAX7219


A ligação dos módulos é muito fácil e realiza-se através de uma porta de série assíncrona SPI, os pinos estão marcados na placa. O pino VCC e GND são os cabos de alimentação e são ligados diretamente ao Arduino aos pinos 5V e GND respetivamente. O pino DIN do módulo é conectado ao pino 8 do Arduino, o pino CLK ao pino 10 e o pino CS ao pino 9 do Arduino.


Para ligar mais módulos, vamos usar a saída que há na parte superior de cada módulo para ligar com a entrada do outro módulo, para mais detalhes veja a imagem do esquema.


Como mostrar texto em scroll


Para começar vamos mostrar um texto em scroll lateral. Para comunicarmos com o módulo, vamos usar a livraria MaxMatrix.h, descarregámo-la usando o link em baixo e descomprimimos na pasta Livrarias da nossa instalação do IDE de Arduino.


DOWNLOAD LIVRARIA MAXMATRIX


O primeiro que fazemos é declarar todos os caracteres possíveis (A-Z e 0-9) como valores binários e, em vez de declará-los como variáveis e colapsar a SRAM, o que faremos é colocar esses dados na memória flash (memória de programa) usando o modificador de variável PROGMEM já que são dados fixos que não variam. A seguir mostramos o sketch que está ligado para que seja muito fácil de entender.


#include <maxmatrix.h>
#include <pgmspace.h>

// DEFINIMOS TODOS OS CARACTERES POSSIVEIS NUM ARRAY
// CARREGAMO-LOS NA MEMÓRIA DE PROGRAMA COM PROGMEM
PROGMEM const unsigned char CH[] = {
3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // espaço
1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // !
3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // "
5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, // #
4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $
5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // %
5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // &
1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // "
3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // (
3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // )
5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, // *
5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // +
2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // ,
4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, // -
2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // .
4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // /
4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0
3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1
4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2
4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3
4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4
4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5
4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6
4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7
4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8
4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9
2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // :
2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, // ;
3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // < 3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // = 3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // >
4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ?
5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @
4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, // A
4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B
4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C
4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D
4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E
4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F
4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G
4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H
3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I
4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J
4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K
4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L
5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M
5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N
4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // O
4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P
4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q
4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R
4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S
5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, // T
4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U
5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V
5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W
5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X
5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y
4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z
2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [
4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, //  
2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ]
3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // chapéu
4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _
2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // `
4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a
4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, // b
4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c
4, 8, B00111000, B01000100, B01000100, B01111111, B00000000, // d
4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // e
3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f
4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g
4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, // h
3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i
4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j
4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k
3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l
5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m
4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n
4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o
4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p
4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q
4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r
4, 8, B01001000, B01010100, B01010100, B00100100, B00000000, // s
3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // t
4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // u
5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, // v
5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // w
5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // x
4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // y
3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // z
3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // {
1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // |
3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // }
4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~
};


// DEFINIMOS OS PINOS DO ARDUINO
int data = 8;    // Pino DIN do módulo MAX7219
int load = 9;    // Pino CS do módulo MAX7219
int clock = 10;  // Pino CLK do módulo MAX7219

// QUANTOS MÓDULOS TEMOS CONECTADOS NA SERIE?
int maxInUse = 2;

// DEFINIMOS A FUNÇÃO DE CADA PINO
MaxMatrix m(data, load, clock, maxInUse);
byte buffer[10];

// ESTA É A VARIÁVEL QUE CONTEM O TEXTO QUE APARECERÁ NOS DISPLAYS
char string1[] = "Isto é um teste de texto em scroll           ";
 
void setup(){
  m.init();          // INICIAMOS O MÓDULO
  m.setIntensity(5); // DEFINIMOS A INTENSIDADE DOS LEDs (0-15)
}
 
void loop(){
  byte c;
  delay(100);  // PAUSA ENTRE MOVIMENTOS
  m.shiftLeft(false, true);
  printStringWithShift(string1, 100);  // ENVIAMOS O TEXTO AOS MÓDULOS
}
 
// FUNÇÕES PARA MOSTRAR OS CARACTERES NO DISPLAY DOS MÓDULOS
void printCharWithShift(char c, int shift_speed){
  if (c < 32) return;
  c -= 32;
  memcpy_P(buffer, CH + 7*c, 7);
  m.writeSprite(maxInUse*8, 0, buffer);
  m.setColumn(maxInUse*8 + buffer[0], 0);
 
  for (int i=0; i<buffer[0]+1; i++)
  {
    delay(shift_speed);
    m.shiftLeft(false, false);
  }
}
 
void printStringWithShift(char* s, int shift_speed){
  while (*s != 0){
    printCharWithShift(*s, shift_speed);
    s++;
  }
}

Mostrar desenhos ou padrões


Usar matrices de leds no nosso projeto é uma boa forma de incorporar sinais de aviso, alertas de estado ou simplesmente animações engraçadas. Neste caso vamos ver como alterar imagens para criar uma animação simples de 2 frames usando a livraria  LEDControl.h.


Tal como na outra livraria, descrregamo-la e descomprimimos na pasta Livrarias da inatalação do IDE do Arduino. O código está comentado para que seja fácil de entender. Aqui está o link para ser descarregado:


DESCARREGAR LIVRARIA LEDCONTROL


//Incluimos a livraria LedControl.h
#include "LedControl.h"

//Declaramos os pinos: DIN, CLK, CS y el nº de displays conectados em serie
LedControl lc=LedControl(8,10,9,2);

//Pausa entre frames  
unsigned long delayTime=900;  
 
//Codigo dos 2 frames que vamos mostrar:
//Coração pequeno
byte Heart1[] = {
B00000000,
B01100110,
B11111111,
B11111111,
B01111110,
B00111100,
B00011000,
B00000000};

//Coração grande
byte Heart2[] = {
B01100110,
B11111111,
B11111111,
B11111111,
B11111111,
B01111110,
B00111100,
B00011000};

//Sub para transformar array #1 num padrão para a matriz
void Heart1GO()
{
  for (int i = 0; i < 8; i++)  
  {
    lc.setRow(0,i,Heart1[i]);
    lc.setRow(1,i,Heart2[i]);
  }
}

//Sub para transformar array #2 num padrão para a matriz
void Heart2GO()
{
  for (int i = 0; i < 8; i++)  
  {
    lc.setRow(0,i,Heart2[i]);
    lc.setRow(1,i,Heart1[i]);
  }
}

//Esta sub vai-se executar 1 só vez ao arrancar o Arduino
void setup() {
lc.shutdown(0,false);    //Iniciamos a matriz led #1
lc.shutdown(1,false);  //Iniciamos a matriz led #2
lc.setIntensity(0,5);    //Intensidade dos led na matriz #1
lc.setIntensity(1,5);  //Intensidade dos led na matriz #2
lc.clearDisplay(0);      //Apagamos todos os led da matriz #1
lc.clearDisplay(1);    //Apagamos todos os led da matriz #2
}

//Esta sub vai-se executar num laço uma e outra vez enquanto o Arduino esteja alimentado.
void loop() {
Heart1GO();         //Mostramos o padrão #1
delay(delayTime);   //Pequena pausa
Heart2GO();         //Mostramos o padrão #2
delay(delayTime);   //Pequena pausa
}

Criando padrões em binário


Como já vimos nos exemplos anteriores, cada digito ou caracter é composto de um código em binário que define o estado de cada led da matriz. Para gerar estes códigos de forma fácil e rápida, desenhamos uma pequena aplicação para Windows baseada numa ferramenta online que descobrimos há algum tempo.


VER FERRAMENTA ONLINE



Como se pode ver na imagem, está formado por uma matriz de 8×8 checkboxes, cada checkbox define o estado de 1 led da matriz. Para gerar um padrão, marcamos os checkbox desejados até confirmar uma imagem ao estilo pixel art. Na seguinte imagem vê-se um coração gerado pelo programa.



Podemos gerar os nosso próprios padrões para integrá-los em qualquer sketch de forma fácil e lembre-se, se o checkbox está marcado o led vai estar ativado na matriz.


DESCARREGAR APLICAÇÃO (BETA)



15
Projetos / Programar um ATtiny85 com Arduino UNO
« Online: Dezembro 08, 2017, 09:19:50 am »
Programar um ATtiny85 com Arduino UNO



Neste artigo, vamos ver como programar um Attiny85 com Arduino UNO, sem necessidade de um programador AVR externo.


Preparar o IDE do Arduino


Em primeiro lugar, abrimos o IDE do Arduino e instalamos certos recursos para que reconheça os Attiny85, para isso vamos a Arquivo >> Preferências e abrimos Aditional Boards Manager URLs.


 



 


Na janela que se abre, escrevemos isto: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json e colocamos OK.


A seguir vamos a Ferramentas >> Placa >> Boards Manager e na barra de busca escrevemos “ATtiny”, quando nos aparece no ecrã colocamos INSTALAR.



 


Agora já podemos voltar a Ferramentas >> Placa e selecionar Attiny Repara na imagem como está configurado o IDE do Arduino para gravar um Attiny85:




  • Placa: ATtiny

  • Processador:ATtiny85

  • Clock: 1MHz ou 8MHz (Internal) <– SIEMPRE INTERNAL SE NÃO USAR CRISTAL EXTERNO

  • Programador: Arduino as ISP


E com isto já temos o IDE pronto, vamos ver como preparar o Arduino para gravar um Attiny85.



Configurar o Arduino UNO como ISP


Para configurar o Arduino UNO como ISP (In-System Programmer) apenas temos que instalar um pequeno programa que está na galeria de exemplos do IDE do Arduino. Carregamos esse exemplo e instalámo-lo no Arduino e com isto já está preparado.



 


 


Ligar o ATtiny85 ao Arduino UNO


Para ligar o ATtiny85 ao Arduino podemos usar este esquema como referência. Se quiser obter informação enquanto o Arduino UNO funciona como um programador ISP, pode ligar três leds aos pines 9 (POWER), 8 (ERRO) e 7 (PROGRAMAÇÃO). O led de POWER indica que a placa está a funcionar, o de ERROR vai-se acender quando exista algum problema e o led de PROGRAMAÇÃO indica-no quando o Attiny85 está a ser programado.


 


programar_attiny85_con_arduino_uno_fritz


 


LED BLINK com ATtiny85


Agora já temos tudo pronto para escrever o nosso primeiro programa no Attiny85. Vamos testar o mais básico para começar carregando o exemplo BLINK do IDE do Arduino, mas como não trabalhamos com um Arduino mas com um Attiny85, vamos ter que alterar o número dos pinos no nosso código. Pode usar esta imagem como referência, em AZUL tem o número de cada pino.


No código de exemplo a seguir, alterou-se o pino 13 do Arduino pelo pino 0 do Attiny85.


attiny85_pinout


/*
  Neste código de exemplo modificamos o pino 13 do Arduino
  pelo pino 0 do ATtiny85.
 */

void setup() {
  // initialize digital pin 0 as an output.
  pinMode(0, OUTPUT);
}

void loop() {
  digitalWrite(0, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(0, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

Exemplo Blink com ATtiny85


blink_attiny85_ejemplo



Páginas: [1] 2 3 ... 5