Mensagens de Marcelo Rovai - Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)2024-03-29T13:43:24ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovaihttps://storage.ning.com/topology/rest/1.0/file/get/1972339166?profile=RESIZE_48X48&width=48&height=48&crop=1%3A1https://labdegaragem.com/profiles/blog/feed?user=0f4l94zd6aigi&xn_auth=no"IOT feito fácil": Brincando com o ESP32 no Arduino IDEtag:labdegaragem.com,2017-09-26:6223006:BlogPost:6363352017-09-26T22:09:50.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p></p>
<br />
<div class="step-body"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599137?profile=original" target="_self"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599137?profile=RESIZE_1024x1024" width="750"></img></a></p>
<p>Neste tutorial, exploraremos o ESP32, o mais novo dispositivo para uso no campo do IoT. Esta placa, desenvolvida pela <a href="http://www.espressif.com/en/products/hardware/esp32/overview" rel="noopener" target="_blank">Espressif</a>, deverá ser a sucessora do ESP8266, devido ao seu baixo preço e excelentes recursos.</p>
<p>Mas é…</p>
</div>
<p></p>
<br />
<div class="step-body"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599137?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599137?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<p>Neste tutorial, exploraremos o ESP32, o mais novo dispositivo para uso no campo do IoT. Esta placa, desenvolvida pela <a href="http://www.espressif.com/en/products/hardware/esp32/overview" target="_blank" rel="noopener">Espressif</a>, deverá ser a sucessora do ESP8266, devido ao seu baixo preço e excelentes recursos.</p>
<p>Mas é importante alertar que NEM TODAS as bibliotecas ou funções com que você está acostumado a trabalhar com ESP8266 e / ou Arduino estão funcionando nesta nova placa. Provavelmente isso ocorrerá em breve, mas neste momento ainda não estão todas. Confire regularmente o fórum do ESP para saber das atualizações: <a href="https://www.esp32.com/">ESP 32 Forum WebPage</a>.</p>
<p>Aqui, aprenderemos a como programar o ESP32 utilizando-se do Arduino IDE, explorando suas funções e bibliotecas mais comuns, apontar algumas das diferenças importantes com o ESP8266, bem como os novos recursos introduzidos neste grande chip.</p>
<p>Em suma, exploraremos:</p>
<ul>
<li>Saída digital: piscar um LED</li>
<li>Entrada digital: leitura de um sensor de toque</li>
<li>Entrada analógica: leitura de uma tensão variável usando-se de um potenciômetro</li>
<li>Saída analógica: controlando o brilho de um LED</li>
<li>Saída Analógica: Controlando a posição de um Servo</li>
<li>Leitura de dados de temperatura / umidade utilizando-se de um sensor digital</li>
<li>Conectando-se à internet para obter o horário local</li>
<li>Receber dados de uma página web local simples, ligando / desligando um LED</li>
<li>Transmitir dados para uma simples webPage local</li>
<li>Incluir um OLED para apresentar localmente os dados capturados pelo sensor DHT (Temperatura e Umidade), bem como a hora local.</li>
</ul>
<p><img class="lazy-img-onload" src="https://media.giphy.com/media/qdxLVaiWGooak/giphy.gif" alt="" width="700"/></p>
<p> </p>
</div>
<br />
<p></p>
<p></p>
<p></p>
<br />
<h2 id="step1" class="step-title">1 – O ESP32 Características principais</h2>
<div id="photoset-S8PNG3CJ7AQPNMR" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="The ESP32 Main Characterictics" href="https://www.instructables.com/file/FFX77AEJ7AQPNO1/"><img src="https://cdn.instructables.com/FFX/77AE/J7AQPNO1/FFX77AEJ7AQPNO1.MEDIUM.jpg" alt="The ESP32 Main Characterictics"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>O ESP32 é um novíssimo e poderoso componente do mundo do IoT, que mesmo custando menos de US$ 10, possui grandes vantagens em relação à outras placas similares no mercado.</p>
<p>O ESP32 é dual processado, o que ajuda muito principalmente porque quando um processador está manipilando a comunicação, o outro fica responsável pelo controle dos IOs, por exemplo. Este recurso evita alguns problemas de instabilidade que acontecem com o ESP8266, onde uma única CPU precisa parar o que está fazendo quando manipular acomunicação WiFi. Além disso, o ESP32 possui integrado: WIFI, BLUETOOTH, DAC, vários ADC (não apenas um como o ESP8266), sensores de toque capacitivos, etc. (veja o diagrama de blocos acima). E a boa notícia é que o consumo de energia é quase o mesmo que o ESP8266.</p>
<p>Abaixo de um gráfico que pode nos mostrar suas principais características e diferenças do ESP32 quando comparado com ESP8266:</p>
<p><img class="lazy-img-onload" src="https://www.cnx-software.com/wp-content/uploads/2016/03/ESP8266_vs_ESP32.png?raw=true" alt=""/></p>
<p>Ressaltemos seus pontos chave:</p>
<p><strong>Características:</strong></p>
<ul>
<li>240 MHz dual-core Tensilica LX6 microcontroller with 600 DMIPS</li>
<li>Integrated 520 KB SRAM</li>
<li>Integrated 802.11 b/g/n HT40 Wi-Fi transceiver, baseband, stack and LwIP</li>
<li>Integrated dual mode Bluetooth (classic and BLE)</li>
<li>16 MB flash, memory-mapped to the CPU code space</li>
<li>2.3V to 3.6V operating voltage</li>
<li>-40°C to +125°C operating temperature</li>
<li>Onboard PCB antenna / IPEX connector for external antenna</li>
</ul>
<p><strong>Sensores:</strong></p>
<ul>
<li>Ultra-low noise analog amplifier</li>
<li>Hall sensor</li>
<li>10x capacitive touch interfaces</li>
<li>32 kHz crystal oscillator</li>
</ul>
<p><strong>34 x GPIO:</strong></p>
<ul>
<li>3 x UARTs, including hardware flow control</li>
<li>3 x SPI</li>
<li>2 x I2S</li>
<li>18 x ADC input channels</li>
<li>2 x DAC</li>
<li>2 x I2C</li>
<li>PWM/timer input/output available on every GPIO pin</li>
<li>OpenOCD debug interface with 32 kB TRAX buffer</li>
<li>SDIO master/slave 50 MHz</li>
<li>Supports external SPI flash up to 16 MB</li>
<li>SD-card interface support</li>
</ul>
<p><strong>Segurança:</strong></p>
<ul>
<li>WEP, WPA/WPA2 PSK/Enterprise</li>
<li>Hardware accelerated encryption: AES/SHA2/Elliptical Curve Cryptography/RSA-4096</li>
</ul>
<p><strong>Performance:</strong></p>
<ul>
<li>Supports sniffer, Station, SoftAP and Wi-Fi direct mode</li>
<li>Max data rate of 150 Mbps@11n HT40, 72 Mbps@11n HT20, 54 Mbps@11g, and 11 Mbps@11b</li>
<li>Maximum transmit power of 19.5 dBm@11b, 16.5 dBm@11g, 15.5 dBm@11n</li>
<li>Minimum receiver sensitivity of -97 dBm</li>
<li>135 Mbps UDP sustained throughput</li>
<li>5 μA power consumption in Deep-sleep</li>
</ul>
<p> </p>
</div>
<br />
<br />
<h2 id="step2" class="step-title">2: BoM – Lista de materiais</h2>
<div class="step-body"><ul>
<li><a href="https://www.aliexpress.com/store/product/ESP32-Development-Board-WiFi-Bluetooth-Ultra-Low-Power-Consumption-Dual-Cores-ESP-32-ESP-32S-Board/2672017_32778511101.html">ESP32 Development Board</a> (US$ 8.52)</li>
<li><a href="https://www.aliexpress.com/item/0-91-inch-128x32-I2C-IIC-Serial-Blue-OLED-LCD-Display-Module-0-91-12832-SSD1306/32788923016.html?spm=a2g0s.9042311.0.0.sFmTjJ">0.91 inch 128×32 I2C IIC Serial Blue OLED LCD Display </a>(US$2.98)</li>
<li><a href="http://a.co/1qFt3K4">TowerPro SG90 9G Mini Servo</a> (US$ 3.80)</li>
<li><a href="http://a.co/34HHmrU">DHT22/AM2302 Digital Temperature and Humidity Sensor</a> (US$ 9.99)</li>
<li>LED</li>
<li>2 x Resistors: 330 ohm and 10K ohm</li>
<li>Potentiometer: 10K ohm</li>
<li>Protoboards</li>
</ul>
<p> </p>
</div>
<br />
<br />
<h2 id="step3" class="step-title">3: Instalando o IDE do Arduino com o ESP32</h2>
<div id="photoset-SZMBL7JJ7AQNCTL" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="ESP32 Arduino IDE Installation" href="https://www.instructables.com/file/F8T8N5JJ7AQPO6C/"><img src="https://cdn.instructables.com/F8T/8N5J/J7AQPO6C/F8T8N5JJ7AQPO6C.MEDIUM.jpg" alt="ESP32 Arduino IDE Installation"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Usaremos o IDE do Arduino para programar de maneira fácil o ESP32, da mesma maneira que fizemos com o ESP8266.</p>
<p>A maior parte da estrutura já foi implementada pela própria Expressif. A mais notável ausencia ainda é o <em><strong>analogWrite</strong></em>. Enquanto analogWrite está a caminho, existem algumas outras opções que você pode usar:</p>
<ul>
<li>16 canais LEDC que são PWM (exploraremos esta opcão no tutorial)</li>
<li>8 canais SigmaDelta que usa modulação SigmaDelta</li>
<li>DAC de 2 canais que dá saída analógica real</li>
</ul>
<p> </p>
<p><strong>Instalação dos <em>Drivers</em>:</strong></p>
<p>É importante que você tenha instalado em seu computador, o driver “<strong>CP210x USB to UART”</strong>. Entre neste link: <a href="https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers">usb-to-uart-bridge-vcp-drivers</a> e instale o driver apropriado a seu sistema operacional.</p>
<p><strong>Instalando a biblioteca para o IDE32:</strong></p>
<p>A novidade aqui é que a própria Expressif em seu GitHub, nos dará as instruções necessárias para a instalação da biblioteca: <a href="https://github.com/espressif/arduino-esp32">arduino-esp32</a>. Siga as instruções específicas para o seu sistema operacional. Em meu caso (MacOS), a instalação é muito simples:</p>
<p>Abra o Terminal e execute o seguinte comando (copy -> paste e pressione enter):</p>
<p><span style="color: #993300;">mkdir -p ~/Documents/Arduino/hardware/espressif && \ cd ~/Documents/Arduino/hardware/espressif && \ git clone <a href="https://github.com/espressif/arduino-esp32.git">https://github.com/espressif/arduino-esp32.git</a> esp32 && \ cd esp32/tools/ && \ python get.py</span></p>
<p>Em seguida, reinicie o Arduino IDE e pronto! Você verá várias placas no menu “TOOLS”. Selecione a apropriado para você. Em geral, a “genérico” ESP32 DEV MODULE funciona bem.</p>
<blockquote><p>Ao abrir o IDE do Arduino pela primeira vez após a instalação da biblioteca, você notará que a velocidade de upload padrão é de 921,600 bauds. Isso poderá provocar instabilidade. Mude para 115.200 bauds!</p>
</blockquote>
</div>
<br />
<br />
<h2 id="step4" class="step-title">4: Hello World! Piscando um LED</h2>
<div id="photoset-SNNKYLLJ7AQNE80" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Hello World! Blinking a LED" href="https://www.instructables.com/file/FQM7X6BJ7GGGD9O/"><img src="https://cdn.instructables.com/FQM/7X6B/J7GGGD9O/FQM7X6BJ7GGGD9O.MEDIUM.jpg" alt="Hello World! Blinking a LED"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Como de costume, a primeira coisa a fazer quando começamos a explorar um novo HW é piscar um LED.</p>
<p>Vá até o <em>Menu – Examples</em> no IDE e abra o sketch “Blink”.</p>
<p>No caso de minha placa (ESP32 DevKit) ela possui um LED interno conectado ao GPIO 02. É importante verificar se “LED_BUILTIN” é automaticamente reconhecido pelo IDE. Caso contrário, você deve adicionar a linha de código:</p>
<pre>int LED_BUILTIN = 2;</pre>
<blockquote><p>Cada fabricante de placas de desenvolvimento para o ESP32 costuma definir por conta própria a que GPIO o LED interno deverá ser conectado. Não existe um padrão definido, como por exemplo, o “pino 13” no caso do Arduino.</p>
</blockquote>
<p><span style="color: #993300;">/* ESP 32 Blink Turns on an LED on for one second, then off for one second, repeatedly.</span></p>
<p><span style="color: #993300;">The ESP32 has an internal blue LED at D2 (GPIO 02) */</span></p>
<p><span style="color: #993300;">int LED_BUILTIN = 2;</span></p>
<p><span style="color: #993300;">void setup()</span></p>
<p><span style="color: #993300;">{</span></p>
<p><span style="color: #993300;"> pinMode(LED_BUILTIN, OUTPUT);</span></p>
<p><span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span></p>
<p><span style="color: #993300;">{</span></p>
<p><span style="color: #993300;"> digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)</span></p>
<p><span style="color: #993300;"> delay(1000); // wait for a second </span></p>
<p><span style="color: #993300;"> digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW</span></p>
<p><span style="color: #993300;"> delay(1000); // wait for a second</span></p>
<p><span style="color: #993300;">}</span></p>
<p>Abaixo podemos ver o LED interno piscando (observe a luz azul), juntamente com um LED externo conectado ao GPIO 2:</p>
<p><img class="lazy-img-onload" src="https://media.giphy.com/media/gkAL5pRib2Byg/giphy.gif" alt="" width="700"/></p>
<p>Existem várias placas diferentes no mercado e cada uma com uma pinagem diferente. O diagrama acima mostra a pinagem da placa que estou utilizando (<a href="https://www.aliexpress.com/store/product/ESP32-Development-Board-WiFi-Bluetooth-Ultra-Low-Power-Consumption-Dual-Cores-ESP-32-ESP-32S-Board/2672017_32778511101.html">/ESP32-Development-Board)</a></p>
<p>Perfeito! Concluímos que, <strong>DigitalWrite()</strong> está funcionando perfeitamente, da mesma forma que com o ESP8266 e o Arduino. A propósito, <strong>DigitalRead ()</strong> também funcionará da mesma maneira para ler uma entrada digital, como um botão por exemplo.</p>
</div>
<br />
<br />
<h2 id="step5" class="step-title">5: Conhecendo o sensor de toque capacitivo</h2>
<div id="photoset-S51WPR8J7AQPOIC" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="The Touch Sensor" href="https://www.instructables.com/file/FWG3KRCJ7AQPQ5E/"><img src="https://cdn.instructables.com/FWG/3KRC/J7AQPQ5E/FWG3KRCJ7AQPQ5E.MEDIUM.jpg" alt="The Touch Sensor"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Exploremos agora um novo sensor incluído neste chip, o <strong>Touch Sensor, </strong>ou sensor de toque, o qual poderá funcionar como um simples botão por exemplo.</p>
<p>O ESP32 possui 10 sensores de toque capacitivos internos. Esses sensores estão conectados à vários GPIOs:</p>
<ul>
<li>T0: GPIO 4</li>
<li>T1: GPIO 0</li>
<li>T2: GPIO 2</li>
<li>T3: GPIO 15</li>
<li>T4: GPIO 13</li>
<li>T5: GPIO 12</li>
<li>T6: GPIO 14</li>
<li>T7: GPIO 27</li>
<li>T8: GPIO 33</li>
<li>T9: GPIO 32</li>
</ul>
<p>Para lê-los, você deve usar a função: <strong><em>touchRead (Touch Pin #)</em></strong>;</p>
<p>Por exemplo, para ler o Touch Sensor 0 (T0), o qual está associado ao GPIO4, você deverá fazer algo como:</p>
<pre><span style="color: #993300;">int value = touchRead(4);</span></pre>
<p></p>
<p>Criemos um código, onde ao tocarmos o sensor T0 (GPIO4), o LED acenderá.</p>
<blockquote><p>Use o monitor serial para verificar os valores lidos pelo sensor, ajustando o código de acordo ao valor lido.</p>
</blockquote>
<p>Abaixo o código completo:</p>
<p></p>
<p><span style="color: #993300;">/*****************************************************</span> <br/><span style="color: #993300;">* ESP32 Touch Test and LED Ctrl</span><br/><span style="color: #993300;">* Touch pin ==> Touch0 is T0 which is on GPIO 4 (D4).</span><br/><span style="color: #993300;">* LED pin ==> D2</span><br/><span style="color: #993300;">*</span> <br/><span style="color: #993300;">* MJRoBot.org 6Sept17</span><br/><span style="color: #993300;">*****************************************************/</span></p>
<p><span style="color: #993300;">#define TOUTCH_PIN T0 // ESP32 Pin D4</span><br/><span style="color: #993300;">#define LED_PIN 2</span><br/><span style="color: #993300;">int touch_value = 100;</span></p>
<p><span style="color: #993300;">void setup()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> Serial.begin(115200);</span><br/><span style="color: #993300;"> delay(1000); // give me time to bring up serial monitor</span><br/><span style="color: #993300;"> Serial.println("ESP32 Touch Test");</span><br/><span style="color: #993300;"> pinMode(LED_PIN, OUTPUT);</span><br/><span style="color: #993300;"> digitalWrite (LED_PIN, LOW);</span><br/><span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> touch_value = touchRead(TOUTCH_PIN);</span><br/><span style="color: #993300;"> Serial.println(touch_value); // get value using T0</span> <br/><span style="color: #993300;"> if (touch_value < 50)</span><br/><span style="color: #993300;"> {</span><br/><span style="color: #993300;"> digitalWrite (LED_PIN, HIGH);</span><br/><span style="color: #993300;"> }</span><br/><span style="color: #993300;"> else</span><br/><span style="color: #993300;"> {</span><br/><span style="color: #993300;"> digitalWrite (LED_PIN, LOW);</span><br/><span style="color: #993300;"> }</span><br/><span style="color: #993300;"> delay(1000);</span><br/><span style="color: #993300;">}</span></p>
<p>E o GIF nos mostra o sensor funcionando como “um botão”:</p>
<p><img class="lazy-img-onload" src="https://media.giphy.com/media/Yw741LqTPQybu/giphy.gif" alt="" width="700"/></p>
<p> </p>
</div>
<br />
<br />
<h2 id="step6" class="step-title">6: Entradas analógicas</h2>
<div id="photoset-SPK9HAOJ7AQPRDV" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Analog Input" href="https://www.instructables.com/file/F8YU24ZJ7AQPSW1/"><img src="https://cdn.instructables.com/F8Y/U24Z/J7AQPSW1/F8YU24ZJ7AQPSW1.MEDIUM.jpg" alt="Analog Input"/></a></div>
</div>
</div>
</div>
<div class="step-body"><blockquote><p>Existem no total, 18 entradas com capacidade de ler sinais analogicos (ADCs de 12 bits), versus apenas 1 ADC de 10bits no NodeMCU (ESP8266).</p>
</blockquote>
<p> GPIO ADC Channel</p>
<ul>
<li>GPIO 0 ==> ADC2_CH1</li>
<li>GPIO 2 ==> ADC2_CH2</li>
<li>GPIO 4 ==> ADC2_CH0</li>
<li>GPIO 12 => ADC2_CH5</li>
<li>GPIO 13 => ADC2_CH4</li>
<li>GPIO 14 => ADC2_CH6</li>
<li>GPIO 15 => ADC2_CH3</li>
<li>GPIO 25 => ADC2_CH8</li>
<li>GPIO 26 => ADC2_CH9</li>
<li>GPIO 27 => ADC2_CH7</li>
<li>GPIO 32 => ADC1_CH4</li>
<li>GPIO 33 => ADC1_CH5</li>
<li>GPIO 34 => ADC1_CH6</li>
<li>GPIO 35 => ADC1_CH7</li>
<li>GPIO 36 => ADC1_CH0</li>
<li>GPIO 37 => ADC1_CH1</li>
<li>GPIO 38 => ADC1_CH2</li>
<li>GPIO 39 => ADC1_CH3</li>
</ul>
<p>Para ler uma entrada analógica, você vai fazer o mesmo que está acostumado com o Arduino ou o ESP8266, por exemplo apra ler o ADC1_CH0, que está associado ao GPIO 36:</p>
<pre><span style="color: #993300;">int analog_value = analogRead(36);</span></pre>
<p>É muito importante notar que, os ADC do ESP32 possuem 12bits de resolução (versus 10 bits no caso dos ESP8266 e Arduinos), de modo que a faixa total de leitura de ADCs vai de 0 a 4.095 (em vez de 0 a 1.027) quando um sinal de 0 a um máximo de 3.3V é aplicado a uma de suas entradas analógicas.</p>
<p>Como entrada analógica (“sensor”), usaremos um potenciômetro de 10K ohm, conectando-o de 3.3V e GND. Usaremos sua saída variável (pino médio) conectada à entrada de um dos ADC do ESP32. O diagrama acima mostra o potenciômetro conectado ao GPIO 36 que é o canal ADC1 0. Tente também outras entradas em sua placa.</p>
<p>Execute o código abaixo:</p>
<p><span style="color: #993300;">/******************************************************</span> <br/><span style="color: #993300;">* ESP32 Analog Input Test</span> <br/><span style="color: #993300;">* Analog Input: ADC_1_0 pin ==> GPIO36 (VP).</span><br/><span style="color: #993300;">*</span> <br/><span style="color: #993300;">* MJRoBot.org 6Sept17</span><br/><span style="color: #993300;">*****************************************************/</span><br/><span style="color: #993300;">//Analog Input</span><br/><span style="color: #993300;">#define ANALOG_PIN_0 36</span><br/><span style="color: #993300;">int analog_value = 0;</span></p>
<p><span style="color: #993300;">void setup()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> Serial.begin(115200);</span><br/><span style="color: #993300;"> delay(1000); // give me time to bring up serial monitor</span><br/><span style="color: #993300;"> Serial.println("ESP32 Analog IN Test");</span><br/><span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> analog_value = analogRead(ANALOG_PIN_0);</span><br/><span style="color: #993300;"> Serial.println(analog_value);</span><br/><span style="color: #993300;"> delay(500);</span><br/><span style="color: #993300;">}</span></p>
<pre><br/><br/></pre>
<p>Gire o seu potenciômetro e observe no monitor serial do IDE as leituras variando de zero à 4.095.</p>
<p><img class="lazy-img-photoset" src="https://cdn.instructables.com/FOI/UWKG/J7AQQ3I9/FOIUWKGJ7AQQ3I9.MEDIUM.jpg" alt="Analog Input.png"/></p>
</div>
<br />
<br />
<h2 id="step7" class="step-title">7: Saídas analógicas – usando PWM</h2>
<div id="photoset-S4J1LKWJ7AQQBKU" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Dimming a LED: Analog Output Using PWM" href="https://www.instructables.com/file/FSTUXJNJ7AQQG7B/"><img src="https://cdn.instructables.com/FST/UXJN/J7AQQG7B/FSTUXJNJ7AQQG7B.MEDIUM.jpg" alt="Dimming a LED: Analog Output Using PWM"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Para controlar a intencidade de luz de um LED usando ESP8266 ou Arduino, usamos simplesmente o comando analogWrite (), o qual variará o valor PWM de sua saída, simulando um valor analógico. Infelizmente, ainda não temos esse tipo de comando desenvolvido no Arduino IDE para uso com o ESP32. Mas a ótima notícia é que todos os 36 GPIOs do ESP32 possuem a capacidade de gerar saídas PWM, o que é ótimo! Somente deveremos utilizar de uma códificação um pouco mais complexo para alcançar o mesmo resultado.</p>
<p>Programemos um desses GPIOs com um sinal de saída PWM vara ver como funciona.</p>
<blockquote><p>Para mais detalhes, veja este excelente tutorial: <a href="https://techtutorialsx.com/2017/06/15/esp32-arduino-led-pwm-fading/">esp32-arduino-led-pwm-fading</a>.</p>
</blockquote>
<p>A primeira coisa que se deve definir na geração de um sinal PWM, é a sua frequência. Usaremos um valor de 5.000 Hz, que funciona bem com o LED. Devemos também especificar o canal “LED PWM” e a resolução do ciclo de trabalho (PWM duty cycle), em bits. Podemos escolher um canal de 0 a 15 e uma resolução entre 1 e 16 bits. Usaremos o canal 0 e uma resolução de 8 bits.</p>
<pre><span style="color: #993300;">int freq = 5000; </span><br/><span style="color: #993300;">int ledChannel = 0; </span><br/><span style="color: #993300;">int resolution = 8;</span> <br/><br/></pre>
<p>Definamos o GPIO 2, onde está instalado nosso LED externo (e o interno, caso não quiera trabalhar com o LED externo):</p>
<pre><span style="color: #993300;">#define LED_PIN 2</span> <br/><br/></pre>
<p>Esses parâmetros devem ser definidos durante a fase de setup(), usando as seguintes funções:</p>
<p><span style="color: #993300;">void setup()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> ledcSetup(ledChannel, freq, resolution);</span><br/><span style="color: #993300;"> ledcAttachPin(LED_PIN, ledChannel);</span><br/><span style="color: #993300;">}</span></p>
<p>Para ligar o LED com um brilho específico, devemos definir o “ciclo de trabalho” (Duty Cycle). Por exemplo, para desligar o LED, o ciclo de trabalho deve ser zero e a função <em><strong>ledcWrite (ledChannel, dutyCycle)</strong></em> usada para enviar o valor através de um canal PWM específico:</p>
<pre><span style="color: #993300;">int dutyCycle = 0; </span><br/><span style="color: #993300;">ledcWrite(ledChannel, dutyCycle);</span><br/><br/></pre>
<p>Diferentes valores da variável <em><strong>dutyCycle</strong></em> ativarão o LED com um brilho diferente. Esta variável, dutyCycle, variará de 0 a 255, uma vez que a resolução utilizada foi de 8 bits.</p>
<p>Podemos usar o Potenciômetro (associado à variável <em><strong>analog_value</strong></em>) para configurar manualmente a variável <em><strong>dutyCycle. </strong></em>Porém, uma vez que seu intervalo de valores é diferente, usaremos a função <em><strong>map()</strong></em> para relacionar a entrada e a saída:</p>
<pre><span style="color: #993300;">dutyCycle = map(analog_value, 0, 4095, 0, 255);<br/><br/></span></pre>
<p>Abaixo o código completo:</p>
<p><span style="color: #993300;">*****************************************************</span> <br/><span style="color: #993300;">* ESP32 Analog Input/Output Test</span> <br/><span style="color: #993300;">* Analog Input: ADC_1_0 pin ==> GPIO36 (VP).</span><br/><span style="color: #993300;">* PWM LED pin ==> GPIO 02</span><br/><span style="color: #993300;">*</span> <br/><span style="color: #993300;">* MJRoBot.org 6Sept17</span><br/><span style="color: #993300;">*****************************************************/</span><br/><span style="color: #993300;">//Analog Input</span><br/><span style="color: #993300;">#define ANALOG_PIN_0 36</span><br/><span style="color: #993300;">int analog_value = 0;</span></p>
<p><span style="color: #993300;">// PMW LED</span><br/><span style="color: #993300;">#define LED_PIN 2</span><br/><span style="color: #993300;">int freq = 5000;</span><br/><span style="color: #993300;">int ledChannel = 0;</span><br/><span style="color: #993300;">int resolution = 8;</span><br/><span style="color: #993300;">int dutyCycle = 0;</span></p>
<p><span style="color: #993300;">void setup()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> Serial.begin(115200);</span><br/><span style="color: #993300;"> delay(1000); // give me time to bring up serial monitor</span><br/><span style="color: #993300;"> Serial.println("ESP32 Analog IN/OUT Test");</span></p>
<p><span style="color: #993300;"> ledcSetup(ledChannel, freq, resolution);</span><br/><span style="color: #993300;"> ledcAttachPin(LED_PIN, ledChannel);</span><br/><span style="color: #993300;"> ledcWrite(ledChannel, dutyCycle);</span><br/><span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> analog_value = analogRead(ANALOG_PIN_0);</span><br/><span style="color: #993300;"> Serial.println(analog_value);</span><br/><span style="color: #993300;"> dutyCycle = map(analog_value, 0, 4095, 0, 255);</span><br/><span style="color: #993300;"> ledcWrite(ledChannel, dutyCycle);</span><br/><span style="color: #993300;"> delay(500);</span><br/><span style="color: #993300;">}</span></p>
<p>É isso aí! O GIF abaixo mostra os LEDs (interno e externo) variando de intesidade a medida que se varia o potenciometro:</p>
<pre><br/><br/></pre>
<p><img class="lazy-img-onload" src="https://media.giphy.com/media/LTa4zJFsUzQiI/giphy.gif" alt="" width="700"/></p>
<p> </p>
</div>
<br />
<br />
<h2 class="step-title">8: Controlando servo motores</h2>
<div id="photoset-SI95I5LJ7AQRT2Y" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Servo Control" href="https://www.instructables.com/file/FWFR3VJJ7AQRY8Y/"><img src="https://cdn.instructables.com/FWF/R3VJ/J7AQRY8Y/FWFR3VJJ7AQRY8Y.MEDIUM.jpg" alt="Servo Control"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Controlemos um Servo Motor usando as saídas PWM de nosso ESP32. O código será basicamente o mesmo que foi usado para controlar o brilho do LED.</p>
<p>Primeiro, é importante lembrar que a freqüência para trabalhar com um Micro Servo é de 50 Hz, então devemos mudar o parâmetro de freqüência para 50 (em vez de 5.000 usado com o LED). Devemos também especificar o canal LED PWM e a resolução do ciclo de trabalho PWM, em bits. Usaremos novamente o canal 0 e uma resolução de 8 bits.</p>
<p><img class="lazy-img-photoset" src="https://cdn.instructables.com/FOT/6AEF/J7AQRZA0/FOT6AEFJ7AQRZA0.MEDIUM.jpg" alt="servoPWM.png"/></p>
<pre><span style="color: #993300;">int freq = 50; <br/>int channel = 0; <br/>int resolution = 8;</span> <br/><br/></pre>
<p>O servo motor será conectado ao GPIO 5 como mostra o diagrama elétrico acima.</p>
<pre><span style="color: #993300;">#define SERVO_PIN 5</span> <br/><br/></pre>
<p>Da mesma maneira que fizemos com o LED, esses parâmetros devem ser definidos durante a fase de <em><strong>setup()</strong></em>, usando as seguintes funções:</p>
<pre><span style="color: #993300;">void setup() <br/>{ <br/> ledcSetup(channel, freq, resolution); <br/> ledcAttachPin(SERVO_PIN, channel);<br/>}</span> <br/><br/></pre>
<p>Para posicionar o servo em um ângulo específico, devemos definir o “ciclo de trabalho” (veja o diagrama acima).</p>
<p>Por exemplo, para posicionar o servo em torno de 90 graus, o ciclo de trabalho deve ser de cerca de 21 e a função ledcWrite (ledChannel, dutyCycle) deve ser usada para enviar o valor através do canal PWM:</p>
<pre><span style="color: #993300;">int dutyCycle = 21; <br/>ledcWrite(channel, dutyCycle);<br/><br/></span></pre>
<p>Diferentes valores da variável <strong><em>dutyCycle</em></strong> posicionarão o servo com diferentes ângulos. Esta variável, <em><strong>dutyCycle</strong></em>, deve variar de 10 a 32 (esse “range” foi obtido manualmente).</p>
<p>Igual ao que fizemos com o LED, o potenciômetro (conectado a variável <em><strong>analog_value</strong></em>) pode ser usado para configurar manualmente a variável <em><strong>dutyCycle</strong></em> e, assim, mudar a posição do servo. Uma vez que seus intervalos de valores são diferentes, vamos usar a função <em><strong>map()</strong> </em>para relacionar entrada e saída:</p>
<pre><span style="color: #993300;">dutyCycle = map(analog_value, 0, 4095, 10, 33);<br/><br/></span></pre>
<p>Abaixo o código completo:</p>
<p><span style="color: #993300;">/*****************************************************</span> <br/><span style="color: #993300;">* ESP32 Servo Control</span> <br/><span style="color: #993300;">* Analog Input: ADC_1_0 pin ==> GPIO36 (VP).</span><br/><span style="color: #993300;">* PWM SERVO pin ==> GPIO 05</span><br/><span style="color: #993300;">*</span> <br/><span style="color: #993300;">* MJRoBot.org 6Sept17</span><br/><span style="color: #993300;">*****************************************************/</span><br/><span style="color: #993300;">//Analog Input</span><br/><span style="color: #993300;">#define ANALOG_PIN_0 36</span><br/><span style="color: #993300;">int analog_value = 0;</span></p>
<p><span style="color: #993300;">// PMW SERVO</span><br/><span style="color: #993300;">#define SERVO_PIN 5</span><br/><span style="color: #993300;">int freq = 50;</span><br/><span style="color: #993300;">int channel = 0;</span><br/><span style="color: #993300;">int resolution = 8;</span><br/><span style="color: #993300;">int dutyCycle = 21;</span></p>
<p><span style="color: #993300;">void setup()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> Serial.begin(115200);</span><br/><span style="color: #993300;"> delay(1000); // give me time to bring up serial monitor</span><br/><span style="color: #993300;"> Serial.println("ESP32 Servo Control");</span></p>
<p><span style="color: #993300;"> ledcSetup(channel, freq, resolution);</span><br/><span style="color: #993300;"> ledcAttachPin(SERVO_PIN, channel);</span><br/><span style="color: #993300;"> ledcWrite(channel, dutyCycle);</span><br/><span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> analog_value = analogRead(ANALOG_PIN_0);</span><br/><span style="color: #993300;"> Serial.print(analog_value);</span><br/><span style="color: #993300;"> Serial.print(" Duty Cycle ==> ");</span><br/><span style="color: #993300;"> Serial.println(dutyCycle);</span><br/><span style="color: #993300;"> dutyCycle = map(analog_value, 0, 4095, 10, 33);</span><br/><span style="color: #993300;"> ledcWrite(channel, dutyCycle);</span><br/><span style="color: #993300;"> delay(50);</span><br/><span style="color: #993300;">}</span></p>
<p>Agora podemos trabalhar com um sensor ultra-sônico em cima do servo e criar um radar IoT !. Mas este será tema para outro tutorial!</p>
<p><img class="lazy-img-onload" src="https://media.giphy.com/media/8CbYnjPzMlMgE/giphy.gif" alt="" width="700"/></p>
</div>
<br />
<br />
<h2 id="step10" class="step-title">9: Servidor de WiFi</h2>
<div id="photoset-SOQ549CJ7AQRDJA" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Simple WiFi Server" href="https://www.instructables.com/file/FXV4WFCJ7AQRGFZ/"><img src="https://cdn.instructables.com/FXV/4WFC/J7AQRGFZ/FXV4WFCJ7AQRGFZ.MEDIUM.jpg" alt="Simple WiFi Server"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Testemos agora nosso ESP32 como um simples servidor de WiFi.</p>
<ul>
<li>No menu EXEMPLES no IDE do Arduino, abra o sketch ESP32 WiFi / SimpleWiFiServer.ino:</li>
</ul>
<blockquote><p>Este programa “<em>WiFi Web Server LED Blink” </em>foi criado originalmente para arduino em 25 de Novembro de 2012 por Tom Igoe e portado para o Sparkfun esp32 em 31.01.2017 por Jan Hendrik Berlin</p>
</blockquote>
<p>Basicamante, o programa cria um simples servidor web o qual permite o controle de um LED através da web. Este sketch imprimirá o endereço IP da sua rede ESP32 WiFi no Monitor Serial do IDE. A partir daí, você poderá abrir esse endereço em um navegador para ligar e desligar o LED conectado ao GPIO 5 do ESP32.</p>
<p>Se o endereço IP de sua placa for, por exemplo, 10.0.1.40:</p>
<ul>
<li><u><strong><a href="http://10.0.1.40/H">http://10.0.1.40/H </a></strong></u><em>==> Liga o LED</em></li>
</ul>
<ul>
<li><u><strong><a href="http://10.0.1.40/L">http://10.0.1.40/L</a></strong></u><em> ==> Desliga o LED</em></li>
</ul>
<blockquote><p>Este exemplo foi escrito para uma rede usando criptografia WPA. Para WEP ou WPA, mude a função <em>Wifi.begin ()</em>.</p>
</blockquote>
<p>Usaremos o programa sem modificações significativas. Mude o LED externo para GPIO 5</p>
<blockquote><p>Naturalmente se preferir, altere o código para o GPIO 2 sem alterar o HW.</p>
</blockquote>
<p>Entre com as credenciaois de sua rede:</p>
<pre><span style="color: #993300;">const char* ssid = "yourssid"; <br/>const char* password = "yourpasswd";</span> <br/><br/></pre>
<p>E suba o código ao seu ESP32.</p>
<p>A primeira coisa que você verá em seu Monitor Serial, será a informação que o seu ESP32 está conectado e qual é o seu endereço IP:</p>
<pre><span style="color: #0000ff;">WiFi connected. </span><br/><span style="color: #0000ff;">IP address: </span><br/><span style="color: #0000ff;">10.0.1.40</span> <br/><br/></pre>
<p>Abra seu navegador favorito, digitando este endereço IP. Você verá uma WebPage como a mostrada na foto acima. Lá você pode ligar ou desligar o LED remotamente, como mostra o GIF abaixo:</p>
<p><img class="lazy-img-onload" src="https://media.giphy.com/media/ydDsGygb8lZU4/giphy.gif" alt="" width="700"/></p>
<p> </p>
</div>
<br />
<br />
<h2 id="step11" class="step-title">10: DHT 22 – Lendo temperatura e umidade</h2>
<div id="photoset-SB3YCSNJ7AQZFGQ" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="DHT 22 - Reading Temperature and Humidity" href="https://www.instructables.com/file/F9KEZMCJ7AQZFLY/"><img src="https://cdn.instructables.com/F9K/EZMC/J7AQZFLY/F9KEZMCJ7AQZFLY.MEDIUM.jpg" alt="DHT 22 - Reading Temperature and Humidity"/></a></div>
</div>
</div>
<div class="photoset-row cols-2"></div>
</div>
<div class="step-body"><p>Um sensor muito útil para ser usado em projetos IoT é o DHT 11 ou 22. Eles são muito baratos e fáceis de incluir em seus projetos.</p>
<p><img class="lazy-img-photoset" src="https://cdn.instructables.com/F9U/D9N8/J7AQZGBG/F9UD9N8J7AQZGBG.MEDIUM.jpg" alt="Adafruit Unified Sensor Library.png"/></p>
<p>Primeiro, você precisa ter a biblioteca da Adafruit instalada em seu IDE. Vá para o GitHub e faça o download da versão atualizada desta biblioteca: <a href="https://github.com/adafruit/DHT-sensor-library">DHT-sensor-library</a></p>
<blockquote><p>Unzip o arquivo, renomeie-o para DHT e mova a pasta completa para o diretório da de bibliotecas do Arduino</p>
</blockquote>
<p>Quando utilizei a biblioteca pela primeira vez, recebi a seguinte mensagem :</p>
<blockquote><p>fatal error: Adafruit_Sensor.h: No such file or directory</p>
</blockquote>
<p>Depois de pesquisar na web, descobri que também é necessário ter a biblioteca <em><strong>Unified Sensor </strong></em>da Adafruit também instalada. Para instalá-la, utilizei o Arduino IDE Library Manager (veja a imagem acima). Depois disso tudo funcionou bem, da mesma maneira que costumamos fazer com Arduino e NodeMCU.</p>
<p>Executemos alguns testes com este sensor. Siga o diagrama elétrico acima e instale o DHT22 como mostrado:</p>
<blockquote><p>Olhando o sensor com a face “gradeada” voltada para você, conte as 4 pernas da esquerda para a direita</p>
</blockquote>
<ol>
<li>Pin VCC ==> 3.3V</li>
<li>Pin Data ==> GPIO 23</li>
<li>N/C</li>
<li>PIN GND ==> GND</li>
</ol>
<p>Conecte um resistor de10K ohm entre VCC e Data.</p>
<p>Isso aí!</p>
<p>Voce pode utilizar a sketch “DHT tester.ino”, a qual faz parte dos examples incluídos na biblioteca, ou desenvolver o seu próprio.</p>
<p>Escrevi um simples programa como o mostrado abaixo:</p>
<p></p>
<p><span style="color: #993300;">/*****************************************************</span> <br/><span style="color: #993300;">* ESP32 DHT Reading</span> <br/><span style="color: #993300;">* DHT Input: ==> GPIO23.</span><br/><span style="color: #993300;">*</span> <br/><span style="color: #993300;">* MJRoBot.org 9Sept17</span><br/><span style="color: #993300;">*****************************************************/</span></p>
<p><span style="color: #993300;">/* DHT */</span><br/><span style="color: #993300;">#include "DHT.h"</span><br/><span style="color: #993300;">#define DHTPIN 23</span> <br/><span style="color: #993300;">#define DHTTYPE DHT22</span> <br/><span style="color: #993300;">DHT dht(DHTPIN, DHTTYPE);</span><br/><span style="color: #993300;">float localHum = 0;</span><br/><span style="color: #993300;">float localTemp = 0;</span></p>
<p><span style="color: #993300;">void setup()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> Serial.begin(115200);</span><br/><span style="color: #993300;"> delay(1000); // give me time to bring up serial monitor</span><br/><span style="color: #993300;"> Serial.println("");</span><br/><span style="color: #993300;"> Serial.println("ESP32 DHT Temperature and Humidity ");</span><br/><span style="color: #993300;"> Serial.println("");</span><br/><span style="color: #993300;"> dht.begin();</span><br/><span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> getDHT();</span><br/><span style="color: #993300;"> Serial.print("Temp: ==> ");</span><br/><span style="color: #993300;"> Serial.print(localTemp);</span><br/><span style="color: #993300;"> Serial.print(" Hum ==> ");</span><br/><span style="color: #993300;"> Serial.println(localHum);</span><br/><span style="color: #993300;"> delay(2000);</span><br/><span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">/***************************************************</span><br/><span style="color: #993300;">* Get indoor Temp/Hum data</span><br/><span style="color: #993300;">****************************************************/</span><br/><span style="color: #993300;">void getDHT()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> float tempIni = localTemp;</span><br/><span style="color: #993300;"> float humIni = localHum;</span><br/><span style="color: #993300;"> localTemp = dht.readTemperature();</span><br/><span style="color: #993300;"> localHum = dht.readHumidity();</span><br/><span style="color: #993300;"> if (isnan(localHum) || isnan(localTemp)) // Check if any reads failed and exit early (to try again).</span><br/><span style="color: #993300;"> {</span><br/><span style="color: #993300;"> localTemp = tempIni;</span><br/><span style="color: #993300;"> localHum = humIni;</span><br/><span style="color: #993300;"> return;</span><br/><span style="color: #993300;"> }</span><br/><span style="color: #993300;">}</span></p>
<p></p>
<p><img class="alignnone size-full wp-image-13406" src="https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=580" alt="ESP32 DHT Serial Monitor"/>https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=1160 1160w, <a href="https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=150">https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=300">https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=768">https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=768</a> 768w, <a href="https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=1024">https://mjrobot.files.wordpress.com/2017/09/esp32-dht-serial-monitor.png?w=1024</a> 1024w" sizes="(max-width: 580px) 100vw, 580px" /></p>
<p>No print screen do Monitor Serial mostrado acima, você poderá ver o resultado das medidas executadoas com meu programa.</p>
</div>
<br />
<br />
<h2 id="step12" class="step-title">11: Enviando e recebendo dados de uma página local</h2>
<div id="photoset-SB4NQ23J7AR0ZLK" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Sending and Receiving Data From a Local Web Page" href="https://www.instructables.com/file/FFZED95J7AR0ZOT/"><img src="https://cdn.instructables.com/FFZ/ED95/J7AR0ZOT/FFZED95J7AR0ZOT.MEDIUM.jpg" alt="Sending and Receiving Data From a Local Web Page"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Tomaremos os dados gerados a partir do nosso sensor DHT e o valor analógico fornecido pelo potenciômetro, enviando-os para a página web criada para controlar os LEDs.</p>
<p>Comecei com o código SimpleWiFiServer usado na parte 10 deste tutorial e adicionei as linhas de código pertinentes para obter os dados do potenciômetro e DHT.</p>
<blockquote><p>Observe que voltei o LED para o GPIO 2 como você pode ver pelo diagrama elétrico.</p>
</blockquote>
<p>Baixe o código completo do meu GitHub: <a href="https://github.com/Mjrovai/ESP32/blob/master/Playing%20with%20ESP32%20and%20Arduino%20IDE/ESP32_WiFi_Server_Sending_Receiving_Data/ESP32_WiFi_Server_Sending_Receiving_Data.ino">ESP32_WiFi_Server_Sending_Receiving_Data.ino</a></p>
<p>Note que organizei mrlhor o código e agora, o loop () é apenas:</p>
<p><span style="color: #993300;">void loop()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> analog_value = analogRead(ANALOG_PIN_0);</span><br/><span style="color: #993300;"> getDHT();</span><br/><span style="color: #993300;"> WiFiLocalWebPageCtrl();</span><br/><span style="color: #993300;">}</span></p>
<p>A novidade aqui é a função “WiFiLocalWebPageCtrl ()”. Esta função é praticamente a mesma função da configuração original usada no SimpleWebServer(). O que incluí nesta nova função, é o que deve aparecer na página.</p>
<p><span style="color: #993300;">// the content of the HTTP response follows the header:</span><br/><span style="color: #993300;">//WiFiLocalWebPageCtrl();</span> <br/><span style="color: #993300;">client.print("Temperature now is: ");</span><br/><span style="color: #993300;">client.print(localTemp);</span><br/><span style="color: #993300;">client.print(" oC<br>");</span><br/><span style="color: #993300;">client.print("Humidity now is: ");</span><br/><span style="color: #993300;">client.print(localHum);</span><br/><span style="color: #993300;">client.print(" % <br>");</span><br/><span style="color: #993300;">client.print("<br>");</span><br/><span style="color: #993300;">client.print("Analog Data: ");</span><br/><span style="color: #993300;">client.print(analog_value);</span><br/><span style="color: #993300;">client.print("<br>");</span><br/><span style="color: #993300;">client.print("<br>");</span></p>
<p><span style="color: #993300;">client.print("Click <a href=\"/H\">here</a> to turn the LED on.<br>");</span><br/><span style="color: #993300;">client.print("Click <a href=\"/L\">here</a> to turn the LED off.<br>");</span></p>
</div>
<br />
<p></p>
<p>Veja abaixo, o print screen da página web:</p>
<p><img class="lazy-img-photoset" src="https://cdn.instructables.com/FDM/Z5B0/J7AR0ZQE/FDMZ5B0J7AR0ZQE.MEDIUM.jpg" alt="webpage2.png"/></p>
<p></p>
<br />
<div class="step-body"><blockquote><p>Observe que a temperatura, a umidade e os valores analógicos serão atualizados toda vez que você clicar nos links usados no controle de LED ou quando você atualizar a página.</p>
</blockquote>
</div>
<br />
<br />
<div class="step-body"><h2 class="step-title"></h2>
<h2 id="step5" class="step-title">12: Instalando um display OLED</h2>
<div id="photoset-SU9U7E1J7KQPA8A" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Installing the OLED Display" href="https://www.instructables.com/file/FZTIKVXJ7KQPAX7/"><img src="https://cdn.instructables.com/FZT/IKVX/J7KQPAX7/FZTIKVXJ7KQPAX7.MEDIUM.jpg" alt="Installing the OLED Display"/></a></div>
</div>
</div>
<div class="photoset-row cols-2"></div>
</div>
<div class="step-body"><p>Usarei aqui, um display I2C do tipo OLED de 128 x 32. Em princípio, uma vez que você tenha a biblioteca instalada, o ESP32 também funcionará com um display OLED de 128 x 64.</p>
<p>Uma vez que este dispositivo é um display que usa comunicação do tipo <em>I2C</em>, você precisará conectar 4 pinos ao ESP32:</p>
<ul>
<li>SDA ==> GPIO 21</li>
<li>SCL ==> GPIO 22</li>
<li>VCC ==> 3.3V</li>
<li>GND ==> GND</li>
</ul>
<blockquote><p>Veja o diagrama elétrico acima para fazer as conecções corretamente</p>
</blockquote>
<p>Agora, instale a biblioteca. Usaremos aqui a versão de Daniel Eighhoen. Abra o gerenciador da bibliotecas do IDE e procure por “OLED”. Veja a imagem abaixo. Em meu caso, tenho a versão 3.2.7 instalada.</p>
<p><img class="lazy-img-photoset" src="https://cdn.instructables.com/FKH/T7I6/J7GGI1KU/FKHT7I6J7GGI1KU.MEDIUM.jpg" alt="Library.png"/></p>
<p>Uma vez instalada a biblioteca, abra o arquivo: <em><strong>SSD1306SimpleDemo.ino</strong></em>, que se encontra em<strong><em> Examples Menu</em></strong> e troque a linha de código abaixo:</p>
<pre><span style="color: #993300;">SSD1306 display(0x3c, D3, D5);</span></pre>
<p>com:</p>
<pre><span style="color: #993300;">SSD1306 display(0x3c, 21, 22);<br/><br/></span></pre>
<p>O GIF abaixo mostra parte do demo (o GIF tem 10 segundos, mas o demo é um pouco mais longo). Observe também que esta demonstração foi projetada para uma exibição em tela de 128 x 64, como em meu caso, utilizei um display de 128 x 32, os gráficos vão aparecer “achatados”.</p>
<p><img class="lazy-img-onload" src="https://media.giphy.com/media/key4A8EOkHKzC/giphy.gif" alt="" width="700"/></p>
<p> </p>
</div>
<br />
<br />
<h2 id="step6" class="step-title">13: Criando e instalando novas fontes</h2>
<div id="photoset-SZNF3CLJ7KQPCBK" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Hello World 2.PNG" href="https://www.instructables.com/file/FIXR0U5J7GGI1KR/"><img class="lazy-img-photoset" src="https://cdn.instructables.com/FIX/R0U5/J7GGI1KR/FIXR0U5J7GGI1KR.MEDIUM.jpg" alt="Hello World 2.PNG"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Você pode facilmente criar e instalar novas fontes em seu display OLED. Eu por exemplo, criei uma nova fonte que me permite cerca de 2 linhas de 20 caracteres cada uma na tela de um OLED de 128 X 32 .</p>
<p>Como criá-la:</p>
<p><img src="https://cdn.instructables.com/F9B/KXTH/J7GGI1GF/F9BKXTHJ7GGI1GF.MEDIUM.jpg" alt="Creating and Installing New Fonts"/></p>
<p>Vá até o site: <a href="http://modified%20font%20created%20at%20http//oleddisplay.squix.ch/">SSD1306 Font Converter</a>, uma excelente ferramenta criada por Daniel Eighhoen. Uma vez na ferramenta, voce deve escolher:</p>
<ul>
<li>Font Family,</li>
<li>Type (Plan Bold, etc),</li>
<li>Size (10, 20, etc.) e</li>
<li>Library version (em nosso caso deve ser >=3.0.0).</li>
</ul>
<p>Precione <strong><em>Create</em></strong> e voilá! Um arquivo “C Font” será criado na janela (como visto acima).</p>
<ul>
<li>Vá lá e copie o texto para um novo “tab” do IDE.</li>
<li>Nomeie-o, por exemplo: “<em><strong>modified_font.h</strong></em>“</li>
<li>No seu arquivoprincipal .ino , inclua uma nova linha no início do código como abaixo:</li>
</ul>
<pre><span style="color: #993300;">#include "modified_font.h"</span> <br/><br/></pre>
<p>A foto acima, mostra um novo “Hello World”, utilizando-se da nova fonte. O código final poderá ser baixado desde meu GitHub: <a href="https://github.com/Mjrovai/ESP32/tree/master/Playing%20with%20ESP32%20and%20Arduino%20IDE/ESP32%20-%20SSD1306/ESP32_SSD1306_Test">ESP32_SSD1306_Test</a></p>
<p> </p>
</div>
<br />
<br />
<h2 id="step7" class="step-title">14: Mostrando temperatura e humidade no display</h2>
<div id="photoset-SBOY1YIJ7KQPDHS" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Displaying Temperature and Humidity Locally" href="https://www.instructables.com/file/FK3W4JUJ7GGI1MG/"><img src="https://cdn.instructables.com/FK3/W4JU/J7GGI1MG/FK3W4JUJ7GGI1MG.MEDIUM.jpg" alt="Displaying Temperature and Humidity Locally"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Vamos agora exibir no OLED, a temperatura e a umidade capturadas pelo sensor DHT22.</p>
<p>Na nossa função loop (), teremos:</p>
<p><span style="color: #993300;">void loop()</span> <br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> getDHT();</span><br/><span style="color: #993300;"> displayData();</span><br/><span style="color: #993300;"> delay(2000);</span><br/><span style="color: #993300;">}</span></p>
<p>A função getDHT () é a mesma já utilizada anteriormente. A nova função aqui é a displayData (), a qual é mostrado abaixo:</p>
<p><span style="color: #993300;">/***************************************************</span><br/><span style="color: #993300;">* Display Data</span><br/><span style="color: #993300;">****************************************************/</span><br/><span style="color: #993300;">void displayData()</span> <br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> display.clear(); // clear the display</span></p>
<p><span style="color: #993300;"> display.drawString(0, 0, "temp: ");</span><br/><span style="color: #993300;"> display.drawString(40, 0, String(localTemp));</span><br/><span style="color: #993300;"> display.drawString(90, 0, "oC");</span><br/><span style="color: #993300;"> display.drawString(0, 32, "hum: ");</span><br/><span style="color: #993300;"> display.drawString(40, 32, String(localHum));</span><br/><span style="color: #993300;"> display.drawString(90, 32, "%");</span></p>
<p><span style="color: #993300;"> display.display(); // write the buffer to the display</span><br/><span style="color: #993300;"> delay(10);</span><br/><span style="color: #993300;">}</span></p>
<pre>A foto acima, mostra o resultado. O código final poderá ser baixado à partir de meu GitHub: <a href="https://github.com/Mjrovai/ESP32/tree/master/Playing%20with%20ESP32%20and%20Arduino%20IDE/ESP32%20-%20SSD1306/ESP32_DHT22_SSD1306">ESP32_DHT22_SSD1306</a></pre>
</div>
<br />
<br />
<h2 id="step8" class="step-title">15: Incluindo “Time Stamp”</h2>
<div id="photoset-S1HUWG9J7KQPEBW" class="photoset"><div class="photoset-row cols-2"><div class="photoset-cell image-cell"></div>
<div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><img class="alignnone size-full wp-image-13435" src="https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=580" alt="IMG_2697"/>https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=1160 1160w, <a href="https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=150">https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=300">https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=768">https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=768</a> 768w, <a href="https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=1024">https://mjrobot.files.wordpress.com/2017/09/img_2697.png?w=1024</a> 1024w" sizes="(max-width: 580px) 100vw, 580px" /></div>
</div>
</div>
</div>
<div class="step-body"><p>Geralmente, é muito importante ao capturar-se dados com sensores, também registrar o momento em que os mesmos foram coletados.</p>
<p>Instalemos a biblioteca NTPClient para obter a hora exata:</p>
<p><img src="https://cdn.instructables.com/FCW/SY4Z/J7KQPEZN/FCWSY4ZJ7KQPEZN.MEDIUM.jpg" alt="Including Time Stamp"/></p>
<ul>
<li>Abra o Gerenciador de bibliotecas do IDE e procure por “NTP”</li>
<li>Localize e instale a biblioteca NTPClient de Fabrice Weinberg</li>
<li>Abra o exemplo NTP client (pode ser tanto o “basic quanto o Advanced)</li>
</ul>
<p>Altere a linha:</p>
<pre><span style="color: #993300;">#include <ESP8266WiFi.h></span> <br/><br/></pre>
<p>por:</p>
<pre><span style="color: #993300;">#include <WiFi.h></span> <br/><br/></pre>
<p>Entre com suas credenciais para se logar na rede Wi-Fi. No monitor serial, você deverá ver o tempo atual. Na versão básica, a hora local da Europa será mostrada. Na versão avançada, você poderá alterá-lo para sua zona de tempo.</p>
<p>Agora, vamos fundir esse código com o desenvolvido anteriormente. O resultado será o mostrado na foto acima e no monitor seria abaixo:</p>
<p><img class="alignnone size-full wp-image-13438" src="https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=580" alt="Serial Monitor"/>https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=1160 1160w, <a href="https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=150">https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=300">https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=768">https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=768</a> 768w, <a href="https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=1024">https://mjrobot.files.wordpress.com/2017/09/serial-monitor.png?w=1024</a> 1024w" sizes="(max-width: 580px) 100vw, 580px" /></p>
<p>O programa completo poderá ser baixado de meu GitHub: <a href="https://github.com/Mjrovai/ESP32/tree/master/Playing%20with%20ESP32%20and%20Arduino%20IDE/ESP32%20-%20SSD1306/ESP32_Time_Stamp_DHT22_SSD1306">ESP32_Time_Stamp_DHT22_SSD1306</a></p>
<p> </p>
</div>
<br />
<br />
<h2 id="step9" class="step-title">16: Selecionando multiplos displays</h2>
<div class="step-body"><p>Nesta última etapa, colocaremos tudo junto, de maneira que possamos selecionar várias telas diferentes, cada uma com uma informação diferente. Por exemplo:</p>
<ul>
<li>Temperatura</li>
<li>Umidade</li>
<li>Horário local</li>
</ul>
<p>Mas, como podemos mostrar cada uma dessas informações uma a cada vez na tela?</p>
<p>Precisamos para isso, de um mecanismo de “seleção de página”. Existem vários mecanismos diferentes que poderíam ser usados. Normalmente com vários botões, selecionando menus.</p>
<p>Apenas por diversão, vamos tentar algo não usual aqui. O potenciômetro!</p>
<p>Vamos girar o potenciômetro como fazemos com um seletor de rádio e depender do valor lido, vamos definir um “display” específico para ser mostrado no OLED.</p>
<p>Definamos 4 possíveis exibições :</p>
<ol>
<li>display 0 ==> Display OFF</li>
<li>display 1 ==> Hora Local</li>
<li>display 2 ==> Temperatura</li>
<li>display 3 ==> Umidade</li>
<li>display 4 ==> Todas as informações em um único display</li>
</ol>
<p>A entrada analógica pode ler 4,095 valores diferentes. Nós precisamos apenas de 5, então vamos definir intervalos para isso:</p>
<ol>
<li>0000 – 0999: ==> display 0 ==> Display OFF</li>
<li>1000 – 1999: ==> display 1 ==> Hora Local</li>
<li>2000 – 2999: ==> display 2 ==> Temperatura</li>
<li>3000 – 3999: ==> display 3 ==> Umidade</li>
<li>4000 – 4095: ==> display 4 ==> All info</li>
</ol>
<p>Vamos definir uma variável inteira (int) a qual receberá como conteúdo: 0, 1, 2, 3, 4 ou 5, dependendo da tela a ser mostrada:</p>
<pre><span style="color: #993300;">int displayNum = 0;<br/><br/></span></pre>
<p>Agora precisamos criar uma nova função: <em><strong>getDisplay (),</strong></em> a qual lerá o valor do potenciômetro, retornando o número de exibição correto (<em><strong>displayNum</strong></em> será uma variável local dentro desta função):</p>
<p><span style="color: #993300;">/***************************************************</span><br/><span style="color: #993300;">* Get display</span><br/><span style="color: #993300;">****************************************************/</span><br/><span style="color: #993300;">int getDisplay()</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> int displayNum = 0;</span><br/><span style="color: #993300;"> int analog_value = analogRead(ANALOG_PIN_0);</span><br/><span style="color: #993300;"> if (analog_value <= 999) displayNum = 0;</span><br/><span style="color: #993300;"> else if (analog_value > 1000 && analog_value <= 1999) displayNum = 1;</span><br/><span style="color: #993300;"> else if (analog_value > 2000 && analog_value <= 2999) displayNum = 2;</span><br/><span style="color: #993300;"> else if (analog_value > 3000 && analog_value <= 3999) displayNum = 3;</span><br/><span style="color: #993300;"> else if (analog_value > 4000 ) displayNum = 4;</span></p>
<p><span style="color: #993300;"> return displayNum;</span><br/><span style="color: #993300;">}</span></p>
<p></p>
<pre>E a função <em><strong>displayData()</strong></em>, se encarregará de apresentar o display selecionado:<br/><br/></pre>
<p><span style="color: #993300;">/***************************************************</span><br/><span style="color: #993300;">* Display Data</span><br/><span style="color: #993300;">****************************************************/</span><br/><span style="color: #993300;">void displayData(int displayNum)</span> <br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> String formattedTime = timeClient.getFormattedTime();</span><br/><span style="color: #993300;"> display.clear(); // clear the display</span><br/><span style="color: #993300;"> switch (displayNum)</span> <br/><span style="color: #993300;"> {</span><br/><span style="color: #993300;"> case 0:</span><br/><span style="color: #993300;"> display.clear();</span><br/><span style="color: #993300;"> break;</span><br/><span style="color: #993300;"> case 1:</span><br/><span style="color: #993300;"> display.setFont(ArialMT_Plain_24);</span><br/><span style="color: #993300;"> display.drawString(20, 31, String(formattedTime));</span><br/><span style="color: #993300;"> break;</span><br/><span style="color: #993300;"> case 2:</span><br/><span style="color: #993300;"> display.setFont(ArialMT_Plain_24);</span><br/><span style="color: #993300;"> display.drawString(0, 31, "T:");</span><br/><span style="color: #993300;"> display.drawString(30, 31, String(localTemp));</span><br/><span style="color: #993300;"> display.drawString(100, 31, "oC");</span><br/><span style="color: #993300;"> break;</span><br/><span style="color: #993300;"> case 3:</span><br/><span style="color: #993300;"> display.setFont(ArialMT_Plain_24);</span><br/><span style="color: #993300;"> display.drawString(0, 31, "H:");</span><br/><span style="color: #993300;"> display.drawString(30, 31, String(localHum));</span><br/><span style="color: #993300;"> display.drawString(100, 31, "%");</span><br/><span style="color: #993300;"> break;</span><br/><span style="color: #993300;"> case 4:</span><br/><span style="color: #993300;"> display.setFont(Open_Sans_Condensed_Light_20);</span><br/><span style="color: #993300;"> display.drawString(0, 0, "t:");</span><br/><span style="color: #993300;"> display.drawString(10, 0, String(localTemp));</span><br/><span style="color: #993300;"> display.drawString(47, 0, "oC");</span><br/><span style="color: #993300;"> display.drawString(75, 0, "h:");</span><br/><span style="color: #993300;"> display.drawString(85, 0, String(localHum));</span><br/><span style="color: #993300;"> display.drawString(120, 0 , "%");</span><br/><span style="color: #993300;"> display.setFont(ArialMT_Plain_24);</span><br/><span style="color: #993300;"> display.drawString(20, 31, String(formattedTime));</span><br/><span style="color: #993300;"> break;</span><br/><span style="color: #993300;"> default:</span> <br/><span style="color: #993300;"> display.clear();</span><br/><span style="color: #993300;"> break;</span><br/><span style="color: #993300;"> }</span><br/><span style="color: #993300;"> display.display(); // write the buffer to the display</span><br/><span style="color: #993300;"> delay(10);</span><br/><span style="color: #993300;">}</span></p>
<pre><br/>Ambas funções deverão fazer parte do loop():<br/><br/></pre>
<p><span style="color: #993300;">void loop()</span> <br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> getDHT();</span><br/><span style="color: #993300;"> timeClient.update();</span><br/><span style="color: #993300;"> displayData(getDisplay());</span><br/><span style="color: #993300;"> delay(2000);</span><br/><span style="color: #993300;">}</span></p>
<p></p>
<pre>O arquivo completo poderá ser baixado de meu GitHub: <a href="https://github.com/Mjrovai/ESP32/tree/master/Playing%20with%20ESP32%20and%20Arduino%20IDE/ESP32%20-%20SSD1306/ESP32_Time_Stamp_DHT22_SSD1306_Multiple_Displays">ESP32_Time_Stamp_DHT22_SSD1306_Multiple_Displays</a></pre>
<p>Abaixo o GIF mostrando a seleção de displays a prtir do potenciômetro:</p>
<p><img class="lazy-img-onload" src="https://media.giphy.com/media/qdxLVaiWGooak/giphy.gif" alt="" width="700"/></p>
<p>Uma outra opção legal para selecionar os displays é através de botões. No caso do ESP32, isto podería ser feito com os “sensores de toque”. O codigo não sería muito diferente do mostrado aqui. Fica a sugestão!</p>
<p> </p>
</div>
<br />
<br />
<h2 id="step10" class="step-title">17: Conclusão</h2>
<div id="photoset-S4MOEG7J7KQPVEM" class="photoset"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599827?profile=original" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599827?profile=RESIZE_480x480" width="400" class="align-full"/></a></div>
<div class="step-body"><p>Há muito a ser explorado com este ótimo dispositivo IoT. Voltaremos com novos tutoriais! Continue seguindo os tutoriais aqui no site do Garagem, no MJRoBot.org e no Facebook!</p>
<p>Como sempre, espero que este projeto possa ajudar os outros a encontrar seu caminho no excitante mundo da eletrônica, da robótica e do IoT!</p>
<p>Visite meu GitHub para arquivos atualizados: <a href="https://github.com/Mjrovai/ESP32/tree/master/Playing%20with%20ESP32%20and%20Arduino%20IDE" target="_blank" rel="noopener">ESP32</a></p>
<p><em>Saludos desde el sur del mundo</em>!</p>
<p>Até meu próximo tutorial!</p>
<p>Um abraço,</p>
<p>Marcelo</p>
</div>
<br />
</div>
<br />
<p></p>O IoT feito simples: Monitorando múltiplos sensorestag:labdegaragem.com,2017-09-10:6223006:BlogPost:6332672017-09-10T18:24:23.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p></p>
<br />
<div class="photoset" id="photoset-SRHPR1MJ6QQFTA2"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FSJ607NJ6QQFUIV/" title="IoT Made Simple: Monitoring Multiple Sensors"><img alt="IoT Made Simple: Monitoring Multiple Sensors" src="https://cdn.instructables.com/FSJ/607N/J6QQFUIV/FSJ607NJ6QQFUIV.MEDIUM.jpg"></img></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Alguns meses atrás, publiquei um tutorial sobre o monitoramento de temperatura usando o DS18B20, um sensor digital que…</p>
</div>
<p></p>
<br />
<div id="photoset-SRHPR1MJ6QQFTA2" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="IoT Made Simple: Monitoring Multiple Sensors" href="https://www.instructables.com/file/FSJ607NJ6QQFUIV/"><img src="https://cdn.instructables.com/FSJ/607N/J6QQFUIV/FSJ607NJ6QQFUIV.MEDIUM.jpg" alt="IoT Made Simple: Monitoring Multiple Sensors"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Alguns meses atrás, publiquei um tutorial sobre o monitoramento de temperatura usando o DS18B20, um sensor digital que se comunica através de um barramento de um único fio (bus do tipo “1-wire”), sendo os dados enviados pela à internet com a ajuda de um módulo NodeMCU e o aplicativo Blynk:</p>
<p><a href="https://mjrobot.org/2017/01/06/o-iot-feito-simples-monitorando-a-temperatura-desde-qualquer-lugar/">O IoT feito simples: Monitorando a temperatura desde qualquer lugar</a></p>
<p>Mas o que passamos por cima naquele tutorial, foi uma das grandes vantagens desse tipo de sensor que é a possibilidade de coletar dados múltiplos, provenientes de vários sensores conectados ao mesmo barramento de 1 fio (“1-wire”). E agora é hora de também explorá-lo.</p>
<p><img class="lazy-img-photoset" src="https://cdn.instructables.com/FN3/NC0J/J6QQFTA4/FN3NC0JJ6QQFTA4.MEDIUM.jpg" alt="Block Diagram.png"/></p>
<p>Vamos expandir o que foi desenvolvido no último tutorial, monitorando agora dois sensores DS18B20, configurados um em Celsius e outro em Fahrenheit (isto somente para explorar a biblioteca, poderiam ser os dois configurados para Celsius). Os dados serão enviados para uma aplicação Blynk, conforme mostra o diagrama de blocos acima.</p>
</div>
<br />
<p></p>
<p></p>
<p></p>
<br />
<h2 id="step1" class="step-title">1: BoM – Lista de materiais</h2>
<div class="step-body"><ul>
<li><a href="https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/ref=sr_1_fkmr2_3?ie=UTF8&qid=1483559586&sr=8-3-fkmr2&keywords=NodeMCU+ESP+12-E">NodeMCU ESP 12-E</a> (*)</li>
<li>2 X <a href="https://www.amazon.com/dp/B00Q9YBIJI?psc=1">DS18B20 Temperature Sensor</a></li>
<li>1 x Resistor de 4.7K Ohms</li>
<li>BreadBoard</li>
<li>fios</li>
</ul>
<blockquote><p>(*) Qualquer tipo de dispositivo ESP pode ser usado aqui. Os mais comuns são o ESP-01 e o NodeMCU (V2 ou V3). Ambos sempre funcionarão bem. Brevemente publicarei um post explorando também o novíssimo ESP32.</p>
</blockquote>
</div>
<br />
<br />
<h2 class="step-title">2: DS18B20 – Sensor digital de temperatura</h2>
<div id="photoset-S011PA4J6QQFTHU" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="DS18B20 Temperature Sensor" href="https://www.instructables.com/file/FG1WQHAIXGFTY0F/"><img src="https://cdn.instructables.com/FG1/WQHA/IXGFTY0F/FG1WQHAIXGFTY0F.MEDIUM.jpg" alt="DS18B20 Temperature Sensor"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Usaremos neste tutorial uma versão impermeabilizada do sensor DS18B20, a qual é muito útil para se medir remotamente temperaturas remota em condições adversas, por exemplo em um solo úmido. O sensor está isolado e segundo o fabricante, pode medir até 125oC (apesar que a Adafrut não recomenda seu uso em temperaturas superiores a 100oC, devido ao revestimento de PVC do cabo).</p>
<p>O DS18B20 é um sensor digital o que torna ideal so seu uso em longas distâncias! Estes sensores digitais de temperatura de apenas 1 fio, são bastante precisos (± 0,5 °C em grande parte da faixa) fornecendo até 12 bits de precisão a partir de seu conversor digital-analógico integrado.</p>
<p>Eles funcionam muito bem com a família ESP8266, pois utilizam apenas um único pino digital, podendo ser conectados múltiplos sensores neste mesmo pino, pois cada um dos sensores possui um único ID de 64 bits gravado de fábrica para diferenciá-los.</p>
<p>O sensor funciona de 3.0 a 5.0V, o que significa que ele pode ser alimentado diretamente de um dos pinos de 3.3V do NodeMCU.</p>
<p>O sensor possui 3 fios:</p>
<ul>
<li>Preto: GND</li>
<li>Vermelho: VCC</li>
<li>Amarelo: 1-Wire Data</li>
</ul>
<p>Os dados completos do sensor podem ser encontrados no link: <a href="https://cdn-shop.adafruit.com/datasheets/DS18B20.pdf">DS18B20 Datasheet</a></p>
</div>
<br />
<br />
<h2 id="step3" class="step-title">3: Conectando os sensores ao NodeMCU</h2>
<div id="photoset-SHO3XBQJ6QQFTJU" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Connecting the Sensors to NodeMCU" href="https://www.instructables.com/file/FJLPLESJ6QQFTA7/"><img src="https://cdn.instructables.com/FJL/PLES/J6QQFTA7/FJLPLESJ6QQFTA7.MEDIUM.jpg" alt="Connecting the Sensors to NodeMCU"/></a></div>
</div>
</div>
</div>
<div class="step-body"><ol>
<li>Conecte os 3 fios de cada sensor no Mini Breadboard, conforme mostrado na foto acima. Usei conectores especiais para melhor fixação do sensor.</li>
<li>Observe que ambos os sensores estão em paralelo. Se você tiver mais de 2 sensores, você deve fazer o mesmo.</li>
<li>Conecte o cabo vermelho ==> NodeMCU Pin 3.3V</li>
<li>Conecte o cabo preto ==> NodeMCU Pin GND</li>
<li>Conecte o cabo amarelo ==>NodeMCU Pin D4</li>
<li>Use um resistor de 4.7K ohm entre VCC (3.3V) e Dados (D4)</li>
</ol>
</div>
<br />
<br />
<h2 id="step4" class="step-title">4: Instalando as bibliotecas</h2>
<div class="step-body"><p>Para se poder utilizar o DS18B20 com o IDE do Arduino e o ESP8266, será necessário a instalação de duas bibliotecas:</p>
<ol>
<li><a href="https://github.com/adafruit/ESP8266-Arduino/tree/esp8266/libraries/OneWire">OneWire</a></li>
<li><a href="https://github.com/milesburton/Arduino-Temperature-Control-Library">DallasTemperature</a></li>
</ol>
<p>Instale ambas bibliotecas no diretório de bibliotecas do Arduino IDE.</p>
<blockquote><p>Observe que a biblioteca OneWire DEVE OBRIGATORIAMENTE ser a especialmente modificada para ser utilizada com o ESP8266, caso contrário ocorrerá erro durante a compilação. Você encontrará a última versão no link acima.</p>
</blockquote>
</div>
<br />
<br />
<h2 id="step5" class="step-title">5: Testando os sensores</h2>
<div id="photoset-SLNXVHTJ6QQFTQG" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Testing the Sensors" href="https://www.instructables.com/file/F9ELX0HJ6QQFTA6/"><img src="https://cdn.instructables.com/F9E/LX0H/J6QQFTA6/F9ELX0HJ6QQFTA6.MEDIUM.jpg" alt="Testing the Sensors"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Para testar os sensores, baixe de meu GitHub, o arquivo:</p>
<p><a href="https://github.com/Mjrovai/NodeMCU-DS18B20/blob/master/NodeMCU%20Dual%20Temp%20Monitor/NodeMCU_DS18B20_Dual_Sensor_test/NodeMCU_DS18B20_Dual_Sensor_test.ino">NodeMCU_DS18B20_Dual_Se nsor_test.ino</a></p>
<pre>Olhando para o código, podemos notar que as linhas mais importantes são:</pre>
<pre>temp_0 = DS18B20.getTempCByIndex(0); // Sensor 0 will capture Temp in Celcius <br/>temp_1 = DS18B20.getTempFByIndex(1); // Sensor 0 will capture Temp in Fahrenheit</pre>
<p>A primeira linha retornará um valor para o Sensor[0]. que é o sensor mais próximo fisicamente ao pino D4 (veja o “índice (0)”). O valor retornará em Celsius (veja a parte do código: “getTempC”).</p>
<p>A segunda linha está relacionada com sensor seguinte (Sensor[1]) e retornará dados em Fahrenheit. Você poderia ter aqui “n” sensores, desde que defina um “índice” diferente para cada um deles.</p>
<blockquote><p>Utilizei um sensor em Fahrenheit e outro em Celsius apenas para mostrar que é possível fazê-lo diretamente da biblioteca. Em casos reais, ambos os sensores coletaram dados de diferentes tipos, mas normalmente usando o mesmo tipo de medição.</p>
</blockquote>
<p>Carregue agora o código em seu NodeMCU e monitore a temperatura utilizando o Serial Monitor.</p>
<p>A foto acima mostra o resultado esperado. Segure cada um dos sensores em sua mão, você deve ver a temperatura subir.</p>
</div>
<br />
<br />
<h2 id="step6" class="step-title">6: Utilizando o Blynk</h2>
<div class="step-body"><p>Depois de começar a capturar dados de temperatura, é hora de vê-los á partir de qualquer lugar. Vamos fazer isso utilizando-se do App Blynk. Assim, todos os dados capturados serão exibidos em tempo real em seu dispositivo móvel (também construiremos um depósito histórico para isso).</p>
<p><img src="https://cdn.instructables.com/F5U/A3JT/J6QQFTUH/F5UA3JTJ6QQFTUH.MEDIUM.jpg" alt="Using Blynk"/></p>
<p>Siga as etapas abaixo:</p>
<ol>
<li>Crie um novo projeto.</li>
<li>Dê um nome (em meu caso “Dual Temperature Monitor”)</li>
<li>Selecione <em>New Device</em> – <em>ESP8266 (WiFi)</em> como “Meus dispositivos”</li>
<li>Copie o AUTH TOKEN para ser utilizado em seu código (você pode enviá-lo diretamente para o e-mail que tenha cadastrado no Blynk).</li>
<li>Inclui dois Widgets “Gauge”, definindo:<ul>
<li>Pino virtual a ser usado com cada sensor: V10 (Sensor [0]) e V11 (Sensor [1])</li>
<li>A faixa de temperatura: -5 a 100 oC para Sensor [0]</li>
<li>A faixa de temperatura: 25 a 212 oC para Sensor [1]</li>
<li>A frequência para ler dados: 1 segundo</li>
</ul>
</li>
<li>Inclui um widget “Gráfico de histórico”, definindo V10 e V11 como pinos virtuais</li>
<li>Pressione “Play” (o triângulo no canto direito acima)</li>
</ol>
<p>A aplicação Blynk irá dizer-lhe que o NodeMCU está fora de linha. É hora de carregar o código completo no seu IDE Arduino. Você pode obtê-lo aqui:</p>
<p><a href="https://github.com/Mjrovai/NodeMCU-DS18B20/blob/master/NodeMCU%20Dual%20Temp%20Monitor/NodeMCU_Dual_Sensor_Blynk_Ext/NodeMCU_Dual_Sensor_Blynk_Ext.ino">NodeMCU_Dual_Sensor_Blynk_Ext.ino</a></p>
<p>Altere os dados “dummy”, entrando com suas próprias credenciais.</p>
<pre>/* Blynk credentials */ <br/>char auth[] = "YOUR BLYNK AUTH CODE HERE"; <br/>/* WiFi credentials */ <br/>char ssid[] = "YOUR SSID"; <br/>char pass[] = "YOUR PASSWORD";</pre>
<p></p>
<p>E pronto!</p>
<p>Basicamente é o código anterior, onde inserimos os parâmetros Blynk e funções específicas.</p>
<p>Observe as 2 últimas linhas do código, essas são as mais importantes aqui.</p>
<pre>Blynk.virtualWrite(10, temp_0); //virtual pin V10 <br/>Blynk.virtualWrite(11, temp_1); //virtual pin V11</pre>
<p></p>
<p>Se você tiver mais sensores coletando dados, você também deve ter novas linhas equivalentes a estas (com os novos pinos virtuais pertinentes definidos).</p>
<pre><br/>Uma vez que o código esteja carregado e em execução, verifique o aplicativo Blynk.<br/><br/></pre>
<p><img class="lazy-img-photoset" src="https://cdn.instructables.com/FHH/TCA9/J6QQFTUG/FHHTCA9J6QQFTUG.SMALL.jpg" alt="Blynk App Working.png"/></p>
<p>Você deverá ver algo parecido como o mostrado na tela de meu iPhone acima.</p>
</div>
<br />
<br />
<h2 id="step7" class="step-title">7: Conclusão</h2>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979597471?profile=original" target="_self"><img width="200" src="http://storage.ning.com/topology/rest/1.0/file/get/1979597471?profile=RESIZE_320x320" width="200" class="align-full"/></a></p>
<div id="photoset-SS2KW81J6QQFUF0" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><p>Como sempre, espero que este projecto possa ajudar outras pessoas a encontrarem o seu caminho no emocionante mundo da electrónica e do IoT!</p>
<p>Visite minha página do GitHub para verificar se existem arquivos atualizados: <a href="https://github.com/Mjrovai/NodeMCU-DS18B20/tree/master/NodeMCU%20Dual%20Temp%20Monitor">NodeMCU Dual Temp Monitor</a></p>
</div>
</div>
</div>
</div>
<div class="step-body"><p>“Saludos desde el sur del mundo!”</p>
<p class="p1">E por favor não deixe de visitar e seguir minha página: <a href="https://www.facebook.com/mjrobot.org/" target="_blank" rel="noopener">MJRoBot.org no Facebook</a></p>
<p>Até meu próximo tutorial!</p>
<p>Obrigado</p>
<p>Marcelo</p>
</div>
<br />
<p></p>Automação residencial com Alexa e NodeMCU: Emulando um dispositivo WeMotag:labdegaragem.com,2017-08-22:6223006:BlogPost:6300962017-08-22T15:48:16.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="entry-content clearfix" id="content-12795"><div class="photoset" id="photoset-S38C1IJJ6MG1M4D"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><img class="align-left" src="https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=150&width=150" width="150"></img></div>
<div class="photoset-item photoset-image">Alguns meses atrás, explorei como usar a <em>Alexa</em>, um assistente pessoal inteligente, popularizado pelo Amazon Echo e Echo-Dot,em projetos de automação residencial:…</div>
</div>
</div>
</div>
</div>
<div id="content-12795" class="entry-content clearfix"><div id="photoset-S38C1IJJ6MG1M4D" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><img src="https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=150&width=150" width="150" class="align-left"/></div>
<div class="photoset-item photoset-image">Alguns meses atrás, explorei como usar a <em>Alexa</em>, um assistente pessoal inteligente, popularizado pelo Amazon Echo e Echo-Dot,em projetos de automação residencial:</div>
</div>
</div>
</div>
<div class="step-body"><p><a href="https://mjrobot.org/2017/03/24/quando-o-iot-encontra-a-inteligencia-artificial-automacao-residencial-com-alexa-e-nodemcu/" target="_blank" rel="noopener">Quando o IoT encontra a Inteligência Artificial: Automação residencial com Alexa e NodeMCU</a></p>
<p><em>Alexa</em> é capaz de interação de voz, reprodução de música, fazer listas de tarefas, configurar alarmes, podcasts de transmissão, reproduzir audiobooks e fornecer informações meteorológicas, de tráfego e outras informações em tempo real.</p>
<p>A Alexa também pode controlar vários dispositivos inteligentes funcionando como um hub de automação residencial. Usaremos neste projeto, o “Echo-Dot”, que permite aos usuários ativar o dispositivo usando uma palavra de despertar, como “Alexa” ou “Computer”, como em “Star Trek !</p>
<p>No espaço da automação residencial, a Alexa pode interagir com vários dispositivos diferentes como Philips Hue, <strong><em>Belkin Wemo</em></strong>, SmartThings, etc. Em nosso caso, vamos emular o WeMo, usando a biblioteca fauxmoESP.</p>
<blockquote><p>Esta é a principal diferença entre este tutorial e o anterior. A biblioteca fauxmoESP simplifica extremamente o código necessário para o desenvolvimento de projetos de automação residencial envolvendo a Alexa e o NodeMCU.</p>
</blockquote>
<p>WeMo é uma série de produtos da Belkin International, Inc. que permite aos usuários controlar eletrodomésticos desde qualquer lugar. O conjunto de produtos inclui um interruptor, sensor de movimento, interruptor de luz, câmera e aplicativo.</p>
<p>O <em>WeMo Switch</em> (nosso caso aqui) pode ser conectado a qualquer tomada doméstica, a qual pode ser controlada a partir de um smartphone iOS ou Android o qual executará o aplicativo WeMo, via rede doméstica WiFi ou rede celular. Nós emularemos este dispositivo, mas seu controle será obtido por voz via o Echo-Dot.</p>
<p>O diagrama de blocos abaixo mostra o que será desenvolvido em nosso projeto:</p>
<p><a href="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU/blob/master/Version_FauxmoESP/Block_Diagram.png?raw=true" target="_blank"><img src="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU/blob/master/Version_FauxmoESP/Block_Diagram.png?raw=true&width=700" width="700" class="align-full"/></a></p>
<p>O vídeo abaixo mostra como o projeto ficará no final:</p>
<p><a href="https://youtu.be/sZY1pHhq4AA">https://youtu.be/sZY1pHhq4AA</a></p>
<p> </p>
</div>
<br />
<br />
<h2 id="step1" class="step-title">1: Lista de materiais</h2>
<div class="step-body"><p>(Valores em US$ apenas para referência)</p>
<ol>
<li><a href="https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/ref=sr_1_4?ie=UTF8&qid=1489672890&sr=8-4&keywords=NodeMCU+ESP8266-12E">NodeMCU ESP8266-12E</a> ($8.79)</li>
<li><a href="http://a.co/eRj3p3f">Echo Dot (2nd Generation) – Black</a> ($49.99)</li>
<li>2 X <a href="http://a.co/06PTHmB">Mini BreadBoard</a> ($1.00)</li>
<li><a href="http://a.co/cBkb4HD">4-Channel Relay Module</a> ($8.49)</li>
<li><a href="http://a.co/gNPxQfa">Male-Female Dupont Cables</a> ($1.00)</li>
<li>Fonte externa de 5V ou bateria</li>
</ol>
</div>
<br />
<br />
<h2 id="step2" class="step-title">2: Emulação do WeMo – a biblioteca <em>FauxmoESP</em></h2>
<div class="step-body"><p><img class="alignnone size-full wp-image-12791" src="https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=580" alt="WeMo Emulation"/>https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=1160 1160w, <a href="https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=150">https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=300">https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=768">https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=768</a> 768w, <a href="https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=1024">https://mjrobot.files.wordpress.com/2017/08/wemo-emulation.png?w=1024</a> 1024w" sizes="(max-width: 580px) 100vw, 580px" /></p>
<p>Este tutorial baseia-se na excelente biblioteca e exemplo de código aberto desenvolvido por Xosé Perez (<em>Tinkerman</em>). Veja a sua publicação original aqui: <a href="http://tinkerman.cat/emulate-wemo-device-esp8266/">Emulate a WeMo device with ESP8266</a>. Tinkerman por sua vez, baseou-se no código Python desenvolvido por <a href="https://github.com/makermusings/fauxmo">Maker Musings</a>.</p>
<p><strong><em>fauxmoESP</em> </strong>é uma biblioteca para dispositivos baseados em ESP8266 que emula um dispositivo <em>Belkin WeMo</em>, permitindo assim que você os controle usando um protocolo, especialmente desenvolvido para dispositivos, como o Amazon Echo ou o Echo-Dot.</p>
<p>A biblioteca pode ser encontrada no website <em>BitBucket</em> de Xose Perez: <a href="https://bitbucket.org/xoseperez/fauxmoesp">fauxmoESP</a></p>
<p>1. <a href="https://bitbucket.org/xoseperez/fauxmoesp/get/fdf5ffd6793d.zip">fauxmoESP Library ZIP</a></p>
<p>Para que a fauxmoESP funcione, você também precisará de mais 2 bibliotecas, desenvolvidas por Hristo Gochkov:</p>
<p>2. <a href="https://github.com/me-no-dev/ESPAsyncTCP">ESPAsyncTCP</a></p>
<p>3. <a href="https://github.com/me-no-dev/ESPAsyncWebServer">ESPAsyncWebServer</a></p>
<p>Então, vá até o IDE do Arduino e instale as 3 bibliotecas acima no diretório Arduino/Libraries.</p>
<p><strong>Informações técnicas adicionais (e opcionais):</strong></p>
<p>Se você está interessado em entender mais profundamente o que está acontecendo, leia o artigo: <a href="http://hackaday.com/2015/07/16/how-to-make-amazon-echo-control-fake-wemo-devices/">HOW TO MAKE AMAZON ECHO CONTROL FAKE WEMO DEVICES</a>, escrito por Rick Osgut, onde poderá aprender um pouco mais sobre a emulação do WeMo.</p>
<p>Vai aqui um pequeno resumo:</p>
<p><img src="https://cdn.instructables.com/FEE/TRN8/J0IEE08M/FEETRN8J0IEE08M.MEDIUM.jpg" alt="WeMo Emulation - the FauxmoESP Library"/></p>
<p>Os dispositivos <em>WeMo</em> 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 <em>WeMo</em> 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.</p>
<p>O Echo-Dot simplesmente se conectará ao <em>WeMo</em> através da interface HTTP e emitirá um comando do tipo “SetBinaryState”. O <em>WeMo</em> então “obedecerá”, retornando uma confirmação via HTTP. O diagrama acima resume a comunicação entre o Echo-Dote o <em>WeMo Switch</em>. O diagrama acima, resume o protocolo.</p>
</div>
<br />
<br />
<h2 id="step3" class="step-title">3: Criando dispositivos WeMo com a ajuda do NodeMCU</h2>
<div id="photoset-SB2KPT5J6MG1M9B" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" title="Creating Our WeMo Devices With NodeMCU" href="https://www.instructables.com/file/FNL5VESJ6MG1MA2/"><img src="https://cdn.instructables.com/FNL/5VES/J6MG1MA2/FNL5VESJ6MG1MA2.MEDIUM.jpg" alt="Creating Our WeMo Devices With NodeMCU"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Vamos conectar um módulo relé de 4 canais onde controlaremos por exemplo, 2 lâmpadas e 2 tomadas genéricas (“outlets”), conforme mostra o diagrama acima.</p>
<p>Criaremos 4 “dispositivos inteligentes únicos”:</p>
<ul>
<li><strong>Light1</strong> ==> Relay 1 ==> NodeMCU D5</li>
<li><strong>Light2</strong> ==> Relay 3 ==> NodeMCU D7</li>
<li><strong>Outlet1</strong> ==> Relay 2 ==> NodeMCU D6</li>
<li><strong>Outlet2</strong> ==> Relay 4 ==> NodeMCU D8</li>
</ul>
<p>e 3 grupos de dispositivos integrados:</p>
<ul>
<li><strong>All Devices</strong> ==> Light1, Light2, Outlet1 e Outlet2</li>
<li><strong>Living Room</strong> ==> Light1 e Outlet1</li>
<li><strong>Bed Room</strong> ==> Light2 e Outlet2</li>
</ul>
<p>Baixe e abra o código: <a href="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU/blob/master/Version_FauxmoESP/NODEMCU_ALEXA_WeMos_4X_Fauxmo_EXT.ino/NODEMCU_ALEXA_WeMos_4X_Fauxmo_EXT.ino.ino">NODEMCU_ALEXA_WeMos_4X_Fauxmo_EXT.ino</a> desde meu GitHub e altere as credenciais “dummy” pelas de sua rede WiFi:</p>
<p></p>
<p>/* Network credentials */</p>
<p>#define WIFI_SSID "YOUR SSID HERE"</p>
<p>#define WIFI_PASS "YOUR PASSWORD HERE"</p>
<p></p>
<p>defina os pinos do NodeMCU que serão utilizados para acionar os dispositivos individuais</p>
<p>/* Set Relay Pins */</p>
<p>#define RELAY_1 D5</p>
<p>#define RELAY_2 D6</p>
<p>#define RELAY_3 D7</p>
<p>#define RELAY_4 D8</p>
</div>
<br />
<p></p>
<p>Agora, escolha com que nomes (<em>entre aspas</em>) com que a Alexa identificará os dispositivos:</p>
<p>// Device Names for Simulated Wemo switches</p>
<p>fauxmo.addDevice("Light One");</p>
<p>fauxmo.addDevice("Light Two");</p>
<p>fauxmo.addDevice("Outlet One");</p>
<p>fauxmo.addDevice("Outlet Two");</p>
<p>fauxmo.addDevice("Bed Room");</p>
<p>fauxmo.addDevice("Living Room");</p>
<p>fauxmo.addDevice("All Devices");</p>
<pre><br/>Na função setup(), defina qual será a função que responderá aos comandos por voz (aqui a função se chama “callback”):</pre>
<br />
<div class="step-body"><p>fauxmo.onMessage(callback);</p>
<p></p>
<p>Na função setup(), também se deverá chamar a função de setup e conexão com a internet:</p>
<p>//setup and wifi connection</p>
<p>wifiSetup();</p>
<pre><br/>Observe o setup e as condições iniciais para os pinos do NodeMCU:</pre>
<p>//Set relay pins to outputs</p>
<p>pinMode(RELAY_1, OUTPUT);</p>
<p>pinMode(RELAY_2, OUTPUT);</p>
<p>pinMode(RELAY_3, OUTPUT);</p>
<p>pinMode(RELAY_4, OUTPUT);</p>
<p>//Set each relay pin to HIGH</p>
<p>digitalWrite(RELAY_1, HIGH); delay(500);</p>
<p>digitalWrite(RELAY_2, HIGH); delay(500);</p>
<p>digitalWrite(RELAY_3, HIGH); delay(500);</p>
<p>digitalWrite(RELAY_4, HIGH); delay(500);</p>
<blockquote><p>Note que os relés funcionam com “lógica reversa”. HIGH para desligar!</p>
</blockquote>
<p></p>
<p>A função loop() será simplesmente:</p>
<p>void loop() { fauxmo.handle(); }</p>
<pre>A função <strong><em>callback</em></strong> deverá ter o formato como o exemplo abaixo. Aqui só está incluído a porção correspondente ao controle do dispositivo <em>Light1</em>:</pre>
<p>/* ---------------------------------------------------------------- Device Callback -------------------------------------------------------------------*/ void callback(uint8_t device_id, const char* device_name, bool state)</p>
<p>{</p>
<p> Serial.print("Device ");</p>
<p> Serial.print(device_name);</p>
<p> Serial.print(" state: ");</p>
<p> if (state)</p>
<p> {</p>
<p> Serial.println("ON");</p>
<p> }</p>
<p> else</p>
<p> {</p>
<p> Serial.println("OFF");</p>
<p> }</p>
<p></p>
<p>//Switching action on detection of device name</p>
<p> if ( (strcmp(device_name, "Light One") == 0) )</p>
<p> {</p>
<p> if (!state)</p>
<p> {</p>
<p> digitalWrite(RELAY_1, HIGH);</p>
<p> }</p>
<p> else</p>
<p> {</p>
<p> digitalWrite(RELAY_1, LOW);</p>
<p> }</p>
<p> }</p>
<p> ....</p>
<p>}</p>
<blockquote><p>Observe que usei “! State” dentro da “declaração if”, porque os relés de 4 canais usam “lógica reversa” para ativação (LOW para ativar).</p>
</blockquote>
<p></p>
<p>On the Serial monitor you can see the messages exchanged:</p>
<p>[WIFI] Connecting to ROVAI TIMECAP</p>
<p>............................. ==> CONNECTED!</p>
<p>[WIFI] STATION Mode, SSID: ROVAI TIMECAP, IP address: 10.0.1.36</p>
<p></p>
<pre>Agora, necessitamos que a Alexa encontre seu dispositivo. Existem dois métodos para isso:</pre>
<ul>
<li>Utilizando o aplicativo Alexa no smartphone como mostrado nas fotos abaixo. Neste exemplo (não é o nosso aqui), a Alexa encontrará “1 Smart Home device”: <strong>lights</strong> WeMo Switch.</li>
</ul>
<p><img class="alignnone size-full wp-image-9973" src="https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=580" alt="Alexa app"/>https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=1160 1160w, <a href="https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=150">https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=300">https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=768">https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=768</a> 768w, <a href="https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=1024">https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?w=1024</a> 1024w" sizes="(max-width: 580px) 100vw, 580px" /></p>
<ul>
<li>Ou pedindo diretamente à Alexa através de um comando de voz, como por exemplo: “<em>Alexa, Find connected devices</em>”, ou “<em>Computer, discovery devices</em>“, como é o nosso caso, mostrado no vídeo abaixo:</li>
</ul>
<p><a href="https://youtu.be/1ePFDn0hMJ8">https://youtu.be/1ePFDn0hMJ8</a></p>
<p>Uma vez que os dispositivos inteligentes forem descobertos (basta uma única vez), você poderá comandar o Echo-Dot para acioná-los, como mostra o vídeo abaixo:</p>
<p><a href="https://youtu.be/sZY1pHhq4AA">https://youtu.be/sZY1pHhq4AA</a></p>
<p>O screenshot abaixo, mostra para referencia um screenshot to Monitor serial no caso de minha rede e setup:</p>
<p><img class="lazy-img-photoset" src="https://cdn.instructables.com/FEH/EGRE/J6MG1MFJ/FEHEGREJ6MG1MFJ.MEDIUM.jpg" alt="Serial Monitor.png"/></p>
</div>
<br />
<br />
<h2 id="step4" class="step-title">4: Conclusão</h2>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598218?profile=original" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979598218?profile=RESIZE_480x480" width="400" class="align-full"/></a></p>
<div id="photoset-SC9NCPTJ6MG1MIO" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><div class="embed-frame"><div class="figure image_widget"><div class="figcaption embed-figcaption"><p>Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica, robótica e do IoT!</p>
<p>Verifique meu depositário no GitHub para obter os arquivos atualizados:</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="step-body"><p><a href="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU/tree/master/Version_FauxmoESP">Home-Automation-with-Alexa-and-NodeMCU/tree/master/Version_FauxmoESP</a></p>
<p class="p1">E não deixe de visitar e seguir meu blog <a href="https://MJRoBot.org" target="_blank">https://MJRoBot.org</a> e minha página: <a href="https://www.facebook.com/mjrobot.org/" target="_blank" rel="noopener">MJRoBot.org no Facebook</a></p>
<p><em>Saludos desde el sur del mundo</em>!</p>
<p>Até o próximo tutorial!</p>
<p>Obrigado</p>
<p>Marcelo</p>
</div>
<br />
</div>MJRoBot Tutorials - Video 1 - "Introdução ao Arduino"tag:labdegaragem.com,2017-06-08:6223006:BlogPost:6171012017-06-08T15:44:37.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p>Saindo do forno o primeiro vídeo da serie "MJRoBot Tutorials":</p>
<p><strong><span class="font-size-5" style="color: #993300;">"Introdução ao Arduino"</span></strong></p>
<p></p>
<p><a href="https://youtu.be/5a9w8eLiRA8" target="_blank"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979601156?profile=RESIZE_480x480" width="400"></img></a></p>
<p></p>
<p></p>
<p><a href="https://youtu.be/5a9w8eLiRA8">https://youtu.be/5a9w8eLiRA8</a></p>
<p></p>
<p>Espero que gostem!</p>
<p>Um…</p>
<p>Saindo do forno o primeiro vídeo da serie "MJRoBot Tutorials":</p>
<p><strong><span style="color: #993300;" class="font-size-5">"Introdução ao Arduino"</span></strong></p>
<p></p>
<p><a href="https://youtu.be/5a9w8eLiRA8" target="_blank"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979601156?profile=RESIZE_480x480" width="400" class="align-full"/></a></p>
<p></p>
<p></p>
<p><a href="https://youtu.be/5a9w8eLiRA8">https://youtu.be/5a9w8eLiRA8</a></p>
<p></p>
<p>Espero que gostem!</p>
<p>Um abraço</p>IoT feito simples: Controlando servos com o NodeMCU e o Blynktag:labdegaragem.com,2017-05-09:6223006:BlogPost:6116042017-05-09T19:47:40.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="step-container"><div class="photoset" id="photoset-S8ZHOBOJ2GETO81"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a href="https://mjrobot.files.wordpress.com/2017/05/img_1598.jpg?w=768" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2017/05/img_1598.jpg?w=768&width=700" width="700"></img></a></div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Neste tutorial, exploraremos como controlar um servo através da Internet. Para isso, lançaremos mão…</div>
</div>
</div>
</div>
</div>
<div class="step-container"><div id="photoset-S8ZHOBOJ2GETO81" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a href="https://mjrobot.files.wordpress.com/2017/05/img_1598.jpg?w=768" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/05/img_1598.jpg?w=768&width=700" width="700" class="align-full"/></a></div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Neste tutorial, exploraremos como controlar um servo através da Internet. Para isso, lançaremos mão de uma importante dupla de dispositivos no mundo do IoT:</div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">o <em>NodeMCU ESP12-E</em> e o <em>Blynk</em>.<p></p>
<p>Começaremos por aprender como conectar um servo com o NodeMCU, como controlá-lo localmente com um potenciômetro, como ver sua posição em um display e finalmente como controlá-lo através da internet usando um smartphone.</p>
<p>O diagrama de blocos abaixo nos dá uma visão geral do projeto final.</p>
</div>
<div class="photoset-item photoset-image"><img class="alignnone wp-image-11243" src="https://mjrobot.files.wordpress.com/2017/05/servo-control-block-diagram.png" alt="Servo Control Block Diagram" width="675" height="383"/></div>
</div>
</div>
</div>
<div class="step-body"><p>E o vídeo, mostrará o projeto funcionando:</p>
<p><a href="https://www.youtube.com/watch?v=AJlDOx_fKjM">https://www.youtube.com/watch?v=AJlDOx_fKjM</a></p>
<p></p>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 class="step-title"></h2>
<h2 id="step1" class="step-title">1. BoM (Lista de materiais)</h2>
<div id="photoset-SZGGP17J2GEUJK3" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FV8M65RJ2GEV361/"><img src="https://cdn.instructables.com/FV8/M65R/J2GEV361/FV8M65RJ2GEV361.MEDIUM.jpg?width=614" alt="BoM" width="675" height="393"/></a></div>
<div class="photoset-item photoset-image"></div>
<blockquote><div class="photoset-item photoset-image">Valores em USD, apenas para referência.</div>
<div class="photoset-item photoset-image"></div>
</blockquote>
</div>
</div>
</div>
<div class="step-body"><ol>
<li><a href="http://a.co/7k7Fi9y">NodeMCU ESP8266-12E V1.0</a> (US$ 8.79)</li>
<li><a href="http://a.co/dGahAG6">0.96" Inch I2c IIC Serial 128x64 Oled LCD White Display</a> (US$ 9.99)</li>
<li><a href="http://a.co/6cFJNPc">Mg995 Servo 180 Degree</a> (US$ 19.99)</li>
<li><a href="http://a.co/1psTzii">Breadboard Power Supply Module 3.3V/5V</a> (US$ 5.99)</li>
<li><a href="http://a.co/bvK9q94">10K ohms Potentiometer</a> (US$ 7.19)</li>
<li><a href="http://a.co/iAWJPTU">400 points Breadboard</a> (US$ 5.89)</li>
<li><a href="http://a.co/1A8Szj6">Dupont Cables</a> (US$ 7.29)</li>
</ol>
</div>
<div id="double-inline-ads" class="clearfix"></div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step2" class="step-title">2. Conectando o servo e o potenciômetro</h2>
<div id="photoset-S4X0JABJ2GEV4NG" class="photoset"><div class="photoset-row cols-2"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FQF49U1J2GETPN2/"><img class="lazy-img" src="https://cdn.instructables.com/FQF/49U1/J2GETPN2/FQF49U1J2GETPN2.MEDIUM.jpg?width=374.390243902439" alt="IMG_1573.jpg" width="674" height="379"/></a></div>
<div class="photoset-item photoset-image"></div>
</div>
</div>
</div>
<div class="step-body"><p>A primeira coisa que faremos é configurar o NodeMCU para lidar com o Servo, controlando-o através de um potenciômetro de 10K ohm.</p>
<p><img class="alignnone wp-image-11252" src="https://mjrobot.files.wordpress.com/2017/05/servo-pot-block-diagram.png" alt="Servo-Pot Block Diagram" width="674" height="480"/></p>
<blockquote>Cuidado! O NodeMCU é alimentado com 5V, mas todos os seus GPIOs trabalham com um nível de 3.3V.</blockquote>
<p><br/>Dividiremos os barramentos de alimentação do <em>Breadboard</em>, deixando um para 5V e o outro para 3.3V. Para isso, usaremos uma fonte de alimentação específica para <em>Breadboards</em> como a mostrada no diagrama elétrico abaixo:</p>
<p><img class="alignnone wp-image-11255" src="https://mjrobot.files.wordpress.com/2017/05/servo-circuit-1.png" alt="Servo Circuit 1" width="675" height="594"/></p>
<blockquote>NOTA: Durante a fase de desenvolvimento (PC ligado à NodeMCU via porta USB), não é necessário ligar o pino Vin a + 5V (fio vermelho no diagrama), uma vez que a energia será fornecida pelo computador. Deixe-o desconectado.</blockquote>
<p><br/>Para o controle do servo, usaremos a biblioteca:<em> Servo.h :</em></p>
<blockquote><pre><span style="color: #993300;">#include <Servo.h<em>></em> // Include the library</span><br/><span style="color: #993300;">Servo servo1; // Name it "servo1"</span><br/><span style="color: #993300;">#define servo1Pin D2 // Define the NodeMCU pin to attach the Servo</span></pre>
</blockquote>
<p><br/>Durante <em>setup()</em>, a variável <em>servo1</em> deve ser iniciada:</p>
<blockquote><pre><span style="color: #993300;">servo1.attach(servo1Pin);</span></pre>
</blockquote>
<p><br/>O potenciômetro de 10K funcionará como um divisor de tensão, alterando o nível da entrada analógica no NodeMCU (A0) de 0 a 3.3V. Internamente, o ADC de 10 bits (Conversor Analógico-Digital) gerará um valor digital correspondente (de 0 a 1023), armazenado na variável <em>potReading</em>, equivalente à entrada de tensão analógica.</p>
<blockquote><pre><span style="color: #993300;">potReading = analogRead(A0);</span></pre>
</blockquote>
<p><br/>Devemos "mapear" esse valor digital, para que a saída digital modulada por largura de pulso (PWM) do pino D2 varie de 0 a 180 (variável <em>servo1Angle</em>).</p>
<blockquote><pre><span style="color: #993300;">servo1Angle = map(potReading, 0, 1023, 0, 180);</span></pre>
</blockquote>
<p><br/>O servo girará de 0 a 180 graus, utilizando-se do comando abaixo:</p>
<blockquote><pre><span style="color: #993300;">servo1.write(servo1Angle);</span></pre>
</blockquote>
<p><br/>A posição do Servo em graus será exibida, durante esta fase de teste, no Monitor Serial:</p>
<blockquote><pre><span style="color: #993300;">Serial.println(servo1Angle);</span></pre>
</blockquote>
<p><br/>O codigo completo para os testes com o servo, poderá ser descarregado desde meu GitHub:</p>
<p><a href="https://github.com/Mjrovai/IoT-Servo-Control/tree/master/NodeMCU_Servo_Control_Test">NodeMCU_Servo_Control_Test</a></p>
<p></p>
<p>O vídeo abaixo mostra os testes sendo realizados com o servo:</p>
<p><a href="https://www.youtube.com/watch?v=xrtK1I8UyQE">https://www.youtube.com/watch?v=xrtK1I8UyQE</a></p>
<p></p>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step3" class="step-title">3. Instalando um display</h2>
<div id="photoset-S7JTK2NJ2GEWIEE" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/F9UR1G5J2GEWLNI/"><img src="https://cdn.instructables.com/F9U/R1G5/J2GEWLNI/F9UR1G5J2GEWLNI.MEDIUM.jpg?width=614" alt="Let's Display!" width="675" height="638"/></a></div>
</div>
</div>
<div class="photoset-row cols-1"></div>
</div>
<div class="step-body"><p>Esta bem utilizar o Serial Monitor durante os testes, mas o que acontecerá quando você estiver utilizando seu protótipo longe de seu PC em modo autônomo? Para isso, instalaremos um display do tipo <em>OLED</em>, o nosso velho conhecido: SSD1306, cujas principais características são:</p>
<ul>
<li>Tamanho da tela: 0.96 “</li>
<li>Comunicação Serial I2C IIC SPI</li>
<li>128X64</li>
<li>Display de caracteres na cor branca</li>
</ul>
<p><br/>Conecte os pinos do OLED ao NodeMCU, conforme descritos abaixo e no diagrama elétrico acima:</p>
<ul>
<li>SDA ==> D1 (5)</li>
<li>SCL * ==> D2 (4) * Você também poderá encontrar “SDC” ao invés de SCL</li>
<li>VCC ==> 3.3V ou 5V<br/>GND ==> GND</li>
</ul>
<blockquote>O SSD1306 pode ser alimentado tanto com 5V quanto com 3.3V. Usaremos 3.3V fornecidos externamente para não sobrecarregar o NodeMCU.</blockquote>
<p><br/>Depois de conectar o OLED, deveremos baixar e instalar sua biblioteca no IDE do Arduino. Usaremos a biblioteca gráfica desenvolvida por Daniel Eichhorn. Entre no link abaixo e descarregue a biblioteca, instalando-a no IDE do Arduino:</p>
<p><a href="https://github.com/squix78/esp8266-oled-ssd1306" target="_blank" rel="nofollow noopener noreferrer">https://github.com/squix78/esp8266-oled-ssd1306</a></p>
<blockquote>Certifique-se de usar a versão 3.0.0 ou maior!</blockquote>
<p><br/>Depois de reiniciado o IDE, a biblioteca já deverá estar instalada.</p>
<p>A biblioteca suporta o protocolo I2C para acessar a modulo OLED, usando a biblioteca Wire.h:</p>
<blockquote><p><span style="color: #993300;">#include <Wire.h></span> <br/> <span style="color: #993300;">#include "SSD1306.h"</span><br/> <span style="color: #993300;">SSD1306 display(ADDRESS, SDA, SDC);</span></p>
</blockquote>
<p><br/>Listaremos apenas algumas API mais importantes, as quais serão utilizadas com o OLED.</p>
<blockquote>A lista completa poderá ser encontrada no GITHub fornecido anteriormente neste tópico.</blockquote>
<p><br/>A. Controle de exibição do display:</p>
<blockquote><pre><span style="color: #993300;">void init(); // Initialise the display</span><br/><span style="color: #993300;">void displayOn(void); // Turn the display on</span><br/><span style="color: #993300;">void displayOff(void); // Turn the display offs</span><br/><span style="color: #993300;">void clear(void); // Clear the local pixel buffer</span><br/><span style="color: #993300;">void flipScreenVertically(); // Turn the display upside down</span></pre>
</blockquote>
<p><br/>B. Operações com texto:</p>
<blockquote><pre><span style="color: #993300;">void drawString(int16_t x, int16_t y, String text); // (xpos, ypos, "Text")</span><br/><span style="color: #993300;">void setFont(const char* fontData); // Sets the current font.</span></pre>
</blockquote>
<p><br/>Fonts disponíveis:</p>
<ul>
<li>ArialMT_Plain_10,</li>
<li>ArialMT_Plain_16,</li>
<li>ArialMT_Plain_24</li>
</ul>
<p><br/><img class="lazy-img" src="https://cdn.instructables.com/F52/H2PC/J2GETPQE/F52H2PCJ2GETPQE.MEDIUM.jpg?width=614" alt="IMG_1582.jpg" width="676" height="469"/></p>
<p>Uma vez que tenhamos instalado o OLED e sua biblioteca, devemos utilizar um programa simples para testá-lo. Digite o código abaixo em seu IDE, o resultado deverá ser como o mostrado na foto acima:</p>
<p><span style="color: #993300;">/*NodeMCU */</span><br/> <span style="color: #993300;">#include <ESP8266WiFi.h></span></p>
<blockquote><p><span style="color: #993300;">/* OLED */</span><br/> <span style="color: #993300;">#include "SSD1306Wire.h"</span><br/> <span style="color: #993300;">#include "Wire.h"</span><br/> <span style="color: #993300;">const int I2C_DISPLAY_ADDRESS = 0x3c;</span><br/> <span style="color: #993300;">const int SDA_PIN = 0;</span><br/> <span style="color: #993300;">const int SCL_PIN = 2;</span><br/> <span style="color: #993300;">SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SCL_PIN);</span></p>
<p><span style="color: #993300;">void setup ()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;">Serial.begin(115200);</span> <br/> <span style="color: #993300;">displaySetup();</span><br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span> <br/> <span style="color: #993300;">{</span> <br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">/* Initiate and display setup data on OLED */</span><br/> <span style="color: #993300;">void displaySetup()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;">display.init(); // initialize display</span><br/> <span style="color: #993300;">display.clear(); // Clear display</span><br/> <span style="color: #993300;">display.display(); // Put data on display</span><br/> <span style="color: #993300;">Serial.println("Initiating Display Test");</span><br/> <span style="color: #993300;">display.setFont(ArialMT_Plain_24);</span><br/> <span style="color: #993300;">display.drawString(30, 0, "OLED"); // (xpos, ypos, "Text")</span><br/> <span style="color: #993300;">display.setFont(ArialMT_Plain_16);</span><br/> <span style="color: #993300;">display.drawString(18, 29, "Test initiated");</span><br/> <span style="color: #993300;">display.setFont(ArialMT_Plain_10);</span><br/> <span style="color: #993300;">display.drawString(10, 52, "Serial BaudRate:");</span><br/> <span style="color: #993300;">display.drawString(90, 52, String(11500));</span><br/> <span style="color: #993300;">display.display(); // Put data on display</span><br/> <span style="color: #993300;">delay (3000);</span><br/> <span style="color: #993300;">}</span></p>
</blockquote>
<pre><br/><br/></pre>
<p>Se desejar, o codigo acima poderá ser descarregado de meu GitHub:</p>
<p><a href="https://github.com/Mjrovai/IoT-Servo-Control/tree/master/NodeMCU_OLED_Test">NodeMCU_OLED_Test</a></p>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step4" class="step-title">4. Mostrando a posição do servo no OLED</h2>
<div id="photoset-S6TLVEJJ2GEWP02" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FLR7F7EJ2GEWTDI/"><img src="https://cdn.instructables.com/FLR/7F7E/J2GEWTDI/FLR7F7EJ2GEWTDI.MEDIUM.jpg?width=614" alt="Showing the Servo Position in the OLED Display" width="675" height="405"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p></p>
<p>Agora "misturemos" os 2 códigos anteriores, assim poderemos não apenas controlar a posição do servo utilizando-se do potenciômetro, mas também ver sua posição na tela do OLED.</p>
<p></p>
<p>O código completo poderá ser baixado desde meu GitHub:</p>
<p><a href="https://github.com/Mjrovai/IoT-Servo-Control/tree/master/NodeMCU_Servo_Control_Test_OLED">NodeMCU_Servo_Control_Test_OLED</a></p>
<p></p>
<p>E o resultado verificado no video abaixo:</p>
<p><a href="https://www.youtube.com/watch?v=iLsWBcXGV24">https://www.youtube.com/watch?v=iLsWBcXGV24</a></p>
<p></p>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step5" class="step-title">5. Criando a App Blynk para o controle do servo</h2>
<div id="photoset-SJUOWKRJ2GEWTNV" class="photoset"><div class="photoset-row cols-1"></div>
<div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FT0QP5BJ2GETQ6H/"><img class="lazy-img" src="https://cdn.instructables.com/FT0/QP5B/J2GETQ6H/FT0QP5BJ2GETQ6H.MEDIUM.jpg?width=614" alt="IMG_1593.jpg" width="674" height="475"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p></p>
<p>Basicamente, precisaremos alterar o código anterior, incluindo a parte referente ao Blynk mostrada a seguir:</p>
<blockquote><p><span style="color: #993300;">#include <BlynkSimpleEsp8266.h></span><br/> <span style="color: #993300;">char ssid [] = "YOUR SSID";</span><br/> <span style="color: #993300;">char pass [] = "YOUR PASSWORD";</span><br/> <span style="color: #993300;">char auth [] = "YOUR AUTH TOKEN"; // Servo Control Project</span></p>
<p><span style="color: #993300;">/* Reads slider in the Blynk app and writes the value to "potReading" variable */</span></p>
<p><span style="color: #993300;">BLYNK_WRITE(V0)</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;">potReading = param.asInt();</span><br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">/* Display servo position on Blynk app */</span><br/> <span style="color: #993300;">BLYNK_READ(V1)</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;">Blynk.virtualWrite(V1, servo1Angle);</span><br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void setup ()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;">Blynk.begin(auth, ssid, pass);</span><br/> <span style="color: #993300;">}</span><br/> <span style="color: #993300;">void loop()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;">Blynk.run();</span><br/> <span style="color: #993300;">}</span></p>
</blockquote>
<p><br/>Deveremos definir um pino virtual <em>V0</em>, onde o Blynk irá "escrever" (ou "comandar") a posição de servo, da mesma forma que fizemos com o potenciômetro. Na app do Blynk, usaremos um "Slider" (com saída definida de 0 a 1023) que usaremos para comandar a posição do servo.</p>
<p>Outro pino virtual, <em>V1</em>, será utilizado para "ler" a posição do servo, da mesma forma que fazemos com o OLED. Na app do Blynk, usaremos um "Display" (com saída definida de 0 a 180) onde mostraremos a posição do servo.</p>
<p><a href="https://mjrobot.files.wordpress.com/2017/05/blynk.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/05/blynk.png?width=700" width="700" class="align-full"/></a></p>
<p>As fotos acima mostram as telas referents ao app do Blynk.</p>
<p>Voce poderá descarregar o programa complete desde meu GitHub:</p>
<p><a href="https://github.com/Mjrovai/IoT-Servo-Control/tree/master/NodeMCU_Servo_Ctrl_Blynk_EXT">NodeMCU_Servo_Ctrl_Blynk_EXT</a></p>
<p></p>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step6" class="step-title">6. Conclusão</h2>
<div id="photoset-SWF0D10J2GEWZKK" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599987?profile=original" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599987?profile=RESIZE_480x480" width="400" class="align-full"/></a></p>
<p>Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrônica, robótica e do IoT!</p>
<p>Visite o meu depositário de arquivos no GitHub para obter os arquivos atualizados:</p>
<p><a href="https://github.com/Mjrovai/IoT-Servo-Control">IoT-Servo-Control</a></p>
</div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image"><p>Não deixem de visitar e seguir minha página: <a href="https://www.facebook.com/mjrobot.org/" target="_blank" rel="noopener noreferrer">MJRoBot.org no Facebook</a></p>
<p><em>Saludos desde el sur del mundo</em>!</p>
<p>Até o próximo post!</p>
<p>Obrigado</p>
<p>Marcelo</p>
<div class="wpcnt"></div>
</div>
</div>
</div>
</div>
</div>Deteção de cores com o Arduinotag:labdegaragem.com,2017-05-01:6223006:BlogPost:6099792017-05-01T16:02:06.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p><a href="https://mjrobot.files.wordpress.com/2017/05/color-detector.jpg?w=768" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2017/05/color-detector.jpg?w=768&width=700" width="700"></img></a></p>
<p>Neste tutorial, exploraremos como ler cores usando um Arduino e sensores como o TCS 3200. A idéia será detectar a cor de um objeto, exibindo-a em um LCD. Este tutorial é a primeira parte de um projeto maior, um braço robótico que decide que operação executar a partir da cor de uma peça.</p>
<p>O diagrama de blocos abaixo mostra os principais componentes:…</p>
<p></p>
<p><a href="https://mjrobot.files.wordpress.com/2017/05/color-detector.jpg?w=768" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/05/color-detector.jpg?w=768&width=700" width="700" class="align-full"/></a></p>
<p>Neste tutorial, exploraremos como ler cores usando um Arduino e sensores como o TCS 3200. A idéia será detectar a cor de um objeto, exibindo-a em um LCD. Este tutorial é a primeira parte de um projeto maior, um braço robótico que decide que operação executar a partir da cor de uma peça.</p>
<p>O diagrama de blocos abaixo mostra os principais componentes:</p>
<p><a href="https://mjrobot.files.wordpress.com/2017/05/color-detector-block-diagram.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/05/color-detector-block-diagram.png?width=700" width="700" class="align-full"/></a></p>
<p>O vídeo abaixo mostra como ficará o projeto final:</p>
<p><a href="https://youtu.be/WXvYBl_dgA4">https://youtu.be/WXvYBl_dgA4</a></p>
<p></p>
<div class="step-container"><h2 id="step1" class="step-title">1: Lista de materiais (BoM)</h2>
<div class="step-body"><blockquote>Os links e preços abaixo são apenas para referência.</blockquote>
<ol>
<li><a href="http://a.co/gYARS9H">Arduino Nano</a> (US$ 8.00)</li>
<li><a href="http://a.co/abUroLY">TCS3200 Color Sensor Module</a> (US$ 9.00)</li>
<li><a href="http://a.co/ax6KXqf">IIC/I2C/TWI 1602 Serial Blue Backlight LCD Module</a> (US$ 8.00)</li>
<li><a href="http://a.co/bXB22Zx">Breadboard</a> (US$ 2.00)</li>
<li>Cables</li>
</ol>
</div>
<div id="double-inline-ads" class="clearfix"></div>
</div>
<div class="step-container"><h2 id="step2" class="step-title">2: O sensor TSC 3200</h2>
<div id="photoset-S8SZCK1J20PH4HZ" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FV0WQNKJ20PH59F/"><img src="https://cdn.instructables.com/FV0/WQNK/J20PH59F/FV0WQNKJ20PH59F.MEDIUM.jpg?width=614" alt="The TSC 3200 Color Sensor"/></a></div>
</div>
</div>
<div class="photoset-row cols-2"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><p></p>
<p>Como descrito en seu <em><a href="http://www.mouser.com/catalog/specsheets/TCS3200-E11.pdf" target="_blank" rel="noopener noreferrer">Datasheet</a>,</em> O TCS3200 é um conversor programável de luz (cor) em frequência que combina fotodiodos de silício configuráveis e um conversor de corrente em frequência, tudo encapsulado em um único circuito integrado do tipo CMOS.</p>
<p>A saída é um sinal do tipo "onda quadrada" (ciclo de trabalho de 50%) cuja freqüência é diretamente proporcional à intensidade da luz (irradiance). A frequência de saída pode ser escalonada por um dos três valores predefinidos através de dois pinos de entrada de controle (S0 e S1).</p>
</div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Entradas e saída digitais permitem interface direta com um microcontrolador ou outros circuitos lógicos.</div>
</div>
<div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><img class="alignnone size-full wp-image-11110" src="https://mjrobot.files.wordpress.com/2017/05/tsc3200-diagram.png" alt="TSC3200 Diagram" width="588" height="412"/></div>
<div class="photoset-item photoset-image"><em>Output enable</em> (OE) coloca a saída no estado de alta impedância para a partilha de múltiplas unidades de uma linha de entrada do microcontrolador. No TCS3200, o conversor de luz em frequência lê uma matriz 8 x 8 de fotodíodos. O OE (Enable) deve ser conectado a GND (LOW).</div>
<ul>
<li class="photoset-item photoset-image">16 fotodiodos têm filtros azuis,</li>
<li class="photoset-item photoset-image">16 fotodiodos têm filtros verdes,</li>
<li class="photoset-item photoset-image">16 fotodiodos têm filtros vermelhos e</li>
<li class="photoset-item photoset-image">16 fotodiodos são claros sem filtros.</li>
</ul>
<br/>Os pinos S2 e S3 são usados para selecionar qual grupo de fotodíodos (vermelho, verde, azul ou claro) está ativo. Os fotodiodos têm um tamanho de 110 μm x 110 μm e estão em centros de 134 μm.
<p>O Sensor deve ser alimentado entre 2.7 e 5.5VDC. Usaremos a saída 5V do Arduino para alimentar o sensor.</p>
<p>Para usar corretamente o sensor, vamos instalar um pequeno anel de borracha para isolar o sensor da luz lateral. Eu usei cola quente para corrigi-lo.</p>
</div>
</div>
</div>
<div class="step-body"><p><a href="https://mjrobot.files.wordpress.com/2017/05/sensor-with-ring.jpg" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/05/sensor-with-ring.jpg?width=700" width="700" class="align-full"/></a></p>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step3" class="step-title">3: Conectando o HW</h2>
<div id="photoset-S7YX8XIJ20PH8WB" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FX2N8S8J20PHDW6/"><img src="https://cdn.instructables.com/FX2/N8S8/J20PHDW6/FX2N8S8J20PHDW6.MEDIUM.jpg?width=614" alt="Connecting the HW"/></a></div>
</div>
</div>
</div>
<div class="step-body"><ol>
<li>Instale o Arduino Nano no <em>BreadBoard</em></li>
<li>Conecte a saída de 5V e GND do Nano 5Va ambos <em>Power Rails</em> do<em> BreadBoard</em></li>
<li>Conecte o sensor TSC3200 como descrito abaixo:<ul>
<li>S0 ==> Nano pin D4</li>
<li>S1 ==> Nano pin D5</li>
<li>S2 ==> Nano pin D6</li>
<li>S3 ==> Nano pin D7</li>
<li>OUT ==> Nano Pin D8</li>
<li>EN ==> GND</li>
<li>VCC ==> +5V</li>
<li>GND ==> GND</li>
</ul>
</li>
<li>Conecte o <em>I2C LCD 2/16 Serial Display</em> como abaixo:<ul>
<li>SDA ==> Nano Pin A4</li>
<li>SCL ==> Nano Pin A5</li>
</ul>
</li>
</ol>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step4" class="step-title">4: O código do Arduino</h2>
<div id="photoset-S9P09IUJ20PHFLM" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FXMJ8VAJ20PH5RZ/"><img src="https://cdn.instructables.com/FXM/J8VA/J20PH5RZ/FXMJ8VAJ20PH5RZ.MEDIUM.jpg?width=614" alt="The Arduino Code"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>A primeira coisa a definir é a escala de freqüência a ser utilizada, tal como definida na tabela mostrada acima. Os pinos S0 e S1 são usados para isso. A escala da freqüência de saída é útil para otimizar as leituras de sensores para vários contadores de freqüência ou microcontroladores. Definiremos S0 e S1 em HIGH (100%), funcionou bem com meu Nano. Já observei em alguns projectos com o UNO, a frequência escalonada em 20%. Teste para ver o melhor em seu caso.</p>
<pre><span style="color: #993300;"> digitalWrite(s0,HIGH);<br/> digitalWrite(s1,HIGH);<br/></span></pre>
<p><br/>A próxima coisa a fazer é selecionar a cor a ser lida pelo fotodíodo (vermelho, verde ou azul), usamos os pinos de controle S2 e S3 para isso. Como os fotodiodos são conectados em paralelo, o ajuste de S2 e S3 como <em>LOW</em> ou <em>HIGH</em> em combinações diferentes, permite que você selecione diferentes fotodiodos, como mostrado na tabela acima e definidos no código abaixo:</p>
<pre><span style="color: #993300;">void readRGB() </span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;"> red = 0;</span><br/><span style="color: #993300;"> grn = 0;</span><br/><span style="color: #993300;"> blu = 0;</span><br/><span style="color: #993300;"> int n = 10;</span><br/><span style="color: #993300;"> for (int i = 0; i < n; ++i)</span><br/><span style="color: #993300;"> {</span><br/><span style="color: #993300;"> //read red component</span><br/><span style="color: #993300;"> digitalWrite(s2, LOW);</span><br/><span style="color: #993300;"> digitalWrite(s3, LOW);</span><br/><span style="color: #993300;"> red = red + pulseIn(outPin, LOW);</span></pre>
<p><span style="color: #993300;"> </span></p>
<p><span style="color: #993300;"> //read green component</span><br/><span style="color: #993300;"> digitalWrite(s2, HIGH);</span><br/><span style="color: #993300;"> digitalWrite(s3, HIGH);</span><br/><span style="color: #993300;"> grn = grn + pulseIn(outPin, LOW);</span></p>
<p></p>
<p><span style="color: #993300;"> //let's read blue component</span><br/><span style="color: #993300;"> digitalWrite(s2, LOW);</span><br/><span style="color: #993300;"> digitalWrite(s3, HIGH);</span><br/><span style="color: #993300;"> blu = blu + pulseIn(outPin, LOW);</span><br/><span style="color: #993300;"> }</span><br/><span style="color: #993300;"> red = red/n;</span><br/><span style="color: #993300;"> grn = grn/n;</span><br/><span style="color: #993300;"> blu = blu/n;</span><br/><span style="color: #993300;">}</span></p>
<p><br/>Observe que no código acima, leremos algumas vezes cada um dos componentes RGB, tomando uma média, para que com isso possamos reduzir o erro se algumas leituras forem ruins.</p>
<p>Uma vez de posse dos 3 componentes (RGB), deveremos definir a qual cor equivale. A maneira de fazê-lo é "calibrando-se" previamente o projeto. Você pode usar tanto papel quanto objetos com cores conhecidas e assim ler os 3 componentes gerados por este objeto.</p>
<p>Você pode começar com o meu <em>set-up</em>, mudando os parâmetros para o seu nível de luz:</p>
<pre><span style="color: #993300;">void getColor()<br/>{ <br/> readRGB();<br/> if (red > 8 && red < 18 && grn > 9 && grn < 19 && blu > 8 && blu < 16) color = "WHITE"; <br/> else if (red > 80 && red < 125 && grn > 90 && grn < 125 && blu > 80 && blu < 125) color = "BLACK"; <br/> else if (red > 12 && red < 30 && grn > 40 && grn < 70 && blu > 33 && blu < 70) color = "RED"; <br/> else if (red > 50 && red < 95 && grn > 35 && grn < 70 && blu > 45 && blu < 85) color = "GREEN"; <br/> else if (red > 10 && red < 20 && grn > 10 && grn < 25 && blu > 20 && blu < 38) color = "YELLOW"; <br/> else if (red > 65 && red < 125 && grn > 65 && grn < 115 && blu > 32 && blu < 65) color = "BLUE";<br/> else color = "NO_COLOR";<br/>}<br/></span></pre>
<p><br/>Como você pode ver acima tenho predefinido 6 cores: Branco, Preto, Vermelho, Verde, Amarelo e Azul.</p>
<blockquote>À medida que a luz ambiente diminui, os parâmetros tendem a aumentar de valor.</blockquote>
<p><br/>Dentro do loop (), definimos que as leituras são mostradas no LCD a cada 1 segundo.</p>
<p>O código completo pode ser encontrado no meu GitHub:</p>
<p><a href="https://github.com/Mjrovai/Color-Detector">https://github.com/Mjrovai/Color-Detector</a></p>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step5" class="step-title">5: Conclusão</h2>
<div id="photoset-S5AFKKQJ20PHPEW" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599804?profile=original" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599804?profile=RESIZE_320x320" width="300" class="align-full"/></a></p>
<p>Como sempre, espero que este projeto possa ajudar outras pessoas a encontrar o seu caminho no excitante mundo da eletrônica, robótica e do IoT!</p>
<p>Por favor, visite o meu GitHub para arquivos atualizados: <a href="https://github.com/Mjrovai/Color-Detector">Color Detector</a></p>
</div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Não deixem de se inscrever no congresso on-line: <a href="http://www.tudosobreiot.com.br/" target="_blank" rel="noopener noreferrer">Tudo sobre IoT</a>, que acontecerá entre 5 e 8 de junho. Estarei fazendo a palestra: "A revolução Maker e o retorno dos dinossauros!" Nos vemos lá!</div>
<div class="photoset-item photoset-image"><a href="http://www.tudosobreiot.com.br/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/05/iot-congress-banner-mr.jpg?width=700" width="700" class="align-full"/></a></div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Saludos desde el sur del mundo!</div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Até o próximo post!</div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Um abraço e obrigado.</div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Marcelo</div>
</div>
</div>
</div>
</div>Robô controlado por voz via WiFitag:labdegaragem.com,2017-04-04:6223006:BlogPost:6055132017-04-04T18:23:56.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="step-container"><div class="step-body"><p><a href="https://mjrobot.files.wordpress.com/2017/04/img_1357-e1491256445964.png?w=768&h=1&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2017/04/img_1357-e1491256445964.png?w=768&h=1&crop=1&width=700" width="700"></img></a></p>
<p></p>
<p>Em meu último tutorial: <a href="https://mjrobot.org/2017/03/29/controle-ativado-por-voz-com-android-e-nodemcu/" target="_blank">Controle ativado por voz com Android e NodeMCU</a>, exploramos como desenvolver nossa própria App em um smartphone Android para controlar localmente (usando botões…</p>
</div>
</div>
<div class="step-container"><div class="step-body"><p><a href="https://mjrobot.files.wordpress.com/2017/04/img_1357-e1491256445964.png?w=768&h=1&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/04/img_1357-e1491256445964.png?w=768&h=1&crop=1&width=700" width="700" class="align-full"/></a></p>
<p></p>
<p>Em meu último tutorial: <a href="https://mjrobot.org/2017/03/29/controle-ativado-por-voz-com-android-e-nodemcu/" target="_blank">Controle ativado por voz com Android e NodeMCU</a>, exploramos como desenvolver nossa própria App em um smartphone Android para controlar localmente (usando botões ou voz) dispositivos domésticos inteligentes. Que tal agora, em vez de dispositivos domésticos controlarmos motores? E melhor ainda, que tal ter esses motores movendo um robô? Pois isso, é exatamente o que desenvolveremos aqui, um robô controlado por voz via WiFi e utilizando como micro-controlador nosso velho amigo, o NodeMCU!</p>
<p>O diagrama de blocos abaixo nos dá uma geral sobre o projeto que desenvolveremos aqui:</p>
<p><img class="alignnone wp-image-10698" src="https://mjrobot.files.wordpress.com/2017/04/wifi_robot_block_diagram.jpg" alt="WiFi_Robot_Block_Diagram" width="674" height="469"/></p>
<p>e o filme nos mostra como ficará o projeto:</p>
<blockquote>Por favor, considere que um de meus motores estava com muito pouco torque. Apesar de o resultado parecer estranho, o projeto funciona a contento. Assim que mudar o motor, atualizarei o vídeo. Obrigado.</blockquote>
<p></p>
<p><a href="https://youtu.be/UQeTC4ZxvhA">https://youtu.be/UQeTC4ZxvhA</a></p>
</div>
<div class="gpt-ad"></div>
<div id="gpt-ad-native-middle" class="gpt-ad">________________________________</div>
<div class="gpt-ad"></div>
<div class="gpt-ad"></div>
<div class="gpt-ad"><span style="font-size: 1.5em;">1: Lista de materiais (BoM)</span></div>
</div>
<div class="step-container"><div class="step-body"><blockquote>Valores em USD, apenas para referência.</blockquote>
<ol>
<li><a href="https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/ref=sr_1_4?ie=UTF8&qid=1489672890&sr=8-4&keywords=NodeMCU+ESP8266-12E">NodeMCU ESP8266-12E</a> ($8.79)</li>
<li><a href="http://a.co/2nB8LQs">400-point Experiment Breadboard Breadboard</a> ($ 4.97)</li>
<li><a href="https://www.amazon.com/TOOGOO-Push-Pull-Four-Channel-Stepper-Driver/dp/B00K67WDB6/ref=pd_sbs_263_8?_encoding=UTF8&pd_rd_i=B00K67WDB6&pd_rd_r=GXWF91N188WAKQ5RSEFY&pd_rd_w=KFqZO&pd_rd_wg=LUcXi&psc=1&refRID=GXWF91N188WAKQ5RSEFY">H-Bridge L293D</a> ($2.17)</li>
<li><a href="https://www.amazon.com/Emgreat-Chassis-Encoder-wheels-Battery/dp/B00GLO5SMY/ref=pd_sim_421_2?_encoding=UTF8&pd_rd_i=B00GLO5SMY&pd_rd_r=06PS561DZRFKXSAEYEVZ&pd_rd_w=E4ZVu&pd_rd_wg=wdDxb&psc=1&refRID=06PS561DZRFKXSAEYEVZ">Motor Robot Car Chassis Kit</a> ($13.00)</li>
<li><a href="http://a.co/gNPxQfa">Male-Female Dupont Cables</a> ($1.00)</li>
<li><a href="https://www.amazon.com/Portable-Mopower-Lipstick-shaped-Aluminum-External/dp/B00W52JWFK/ref=sr_1_20?s=electronics&ie=UTF8&qid=1491179659&sr=1-20&keywords=5v+iphone+charger">Portable Charger 5VDC 3000mAh Power Bank</a> ($10.00)</li>
<li>Bateria 9V DC</li>
</ol>
<br/>..... e qualquer telefone ou tablet Android!</div>
<div id="double-inline-ads" class="clearfix"><br class="Apple-interchange-newline"/>_________________________</div>
<div class="clearfix"></div>
</div>
<div class="step-container"><h2 id="step2" class="step-title">2: A Ponte-H L293D</h2>
<div id="photoset-SS4FU5PJ0X5BYM0" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"> <img class="alignnone size-full wp-image-10830" src="https://mjrobot.files.wordpress.com/2017/04/l293d.jpg" alt="L293D" width="366" height="365"/></div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Para "drivar" os motores usaremos o L293D.</div>
</div>
</div>
</div>
<div class="step-body"><blockquote><span id="selection-marker-1" class="redactor-selection-marker">De acordo com seu<em> </em></span><em><a href="http://www.ti.com/lit/ds/symlink/l293.pdf">Datasheet</a></em>, o L293D é um controlador do tipo h<em>alf-H </em>quádruplo de alta corrente. O L293D foi projetado para fornecer correntes bidirecionais de até 600 mA em tensões variando de 4,5 V a 36 V.</blockquote>
<br/>Usaremos o CI L293D diretamente com o NodeMCU, em vez de um <em>Shield</em>, como se vê mais comumente em projetos no mercado.
<p>Pois bem, nosso robô terá duas rodas, acionadas por 2 motores DC:</p>
<ul>
<li>Motor esquerdo (LEFT)</li>
<li>Motor direito (RIGHT)</li>
</ul>
<p><br/><img class="alignnone size-full wp-image-10986" src="https://mjrobot.files.wordpress.com/2017/04/nodemcu_l293d_block_diagram2.jpg" alt="NodeMCU_L293D_Block_Diagram" width="366" height="391"/>PWM</p>
<p>Ligaremos os motores ao L293D e este ao NodeMCU, como mostra o diagrama em blocos anterior, onde 6 de seus GPIOs comandarão esses motores.</p>
<p><span style="color: #993300;">int rightMotor2 = 13; // D7 - right Motor -</span><br/> <span style="color: #993300;">int rightMotor1 = 15; // D8 - right Motor +</span><br/> <span style="color: #993300;">int leftMotor2 = 0; // D3 - left Motor -</span> <br/> <span style="color: #993300;">int leftMotor1 = 2; // D4 - left Motor +</span><br/> <span style="color: #993300;">int eneLeftMotor = 12; // D6 - enable Motor Left</span><br/> <span style="color: #993300;">int eneRightMotor = 14; // D5 - enable Motor Right</span></p>
<p><br/>Por exemplo, para mover o robô para a frente, girando o motor esquerdo (LEFT) no sentido apropriado, você deve colocar:</p>
<ul>
<li>HIGH no pino D4 (motor esquerdo +) e</li>
<li>LOW no pino D3 (motor esquerdo -)</li>
</ul>
<p><br/>Para o motor direito (RIGHT) você deve fazer o oposto:</p>
<ul>
<li>HIGH no pino D8 (motor direito +) e</li>
<li>LOW no pino D7 (motor esquerdo -)</li>
</ul>
<p><br/><img src="https://cdn.instructables.com/F7A/XTKM/J0X5DAIS/F7AXTKMJ0X5DAIS.MEDIUM.jpg" alt="The H-Bridge L293D"/></p>
<p>Devido à maneira como meus motores são montados, a combinação acima irá girar ambos motores no mesmo sentido, "empurrando" o robô para a frente.</p>
<p><img class="lazy-img" src="https://cdn.instructables.com/FQB/5MUC/J0X5DAJP/FQB5MUCJ0X5DAJP.MEDIUM.jpg" alt="Robot direction.jpg"/></p>
<blockquote>O diagrama acima define (ou melhor, convenciona) como o robô deverá se mover. Isso é importante para a definição adequada de suas variáveis.</blockquote>
<p><br/>Para controlar a H-Bridge corretamente, você também deverá trabalhar com os pinos de habilitação ("enable"). No exemplo anterior onde o robô se move para a frente, além dos 4 GPIOs discutidos, o robô só funcionaia se os pinos de habilitação (<em>eneLeftMotor</em> e <em>eneRightMotor</em>) estiverem ambos em HIGH. Você poderá conectar esses pinos do L293D (1 e 9) diretamente a + VCC e esquecê-los. Eu não gosto disso, porque se voce necessita por exemplo, parar rapidamente seu robô, esses pinos deveriam estar em necessariamente em LOW. Além disso, associar os pinos de habilitação a saídas PWM do NodeMCU, permitirá também controlar a velocidade do motor. Em nosso exemplo, usaremos estes pinos apenas com valores digitais tais como HIGH e LOW, o que ajustará a velocidade para MAX e ZERO, respectivamente.</p>
<p>Asim, para se criar uma função que conduza nosso robô para a frente, devemos escrever um código como este:</p>
<p><span style="color: #993300;">void forwardMotor(void)</span> <br/> <span style="color: #993300;">{</span><br/><span style="color: #993300;"> digitalWrite(eneLeftMotor,HIGH);</span><br/><span style="color: #993300;"> digitalWrite(eneRightMotor,HIGH);</span><br/><span style="color: #993300;"> digitalWrite(leftMotor1,HIGH);</span><br/><span style="color: #993300;"> digitalWrite(leftMotor2,LOW);</span><br/><span style="color: #993300;"> digitalWrite(rightMotor1,HIGH);</span><br/><span style="color: #993300;"> digitalWrite(rightMotor2,LOW);</span><br/> <span style="color: #993300;">}</span></p>
</div>
</div>
<div class="step-container"><div class="step-container"><div id="double-inline-ads" class="clearfix">___________________________________________________</div>
<div class="clearfix"></div>
</div>
<h2 id="step3" class="step-title">3: Movendo o robô em outras direções</h2>
<div id="photoset-SVFEOEVJ0X5CDCA" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image">Na etapa anterior, aprendemos como podemos mover o robô para a frente, pensemos agora como movê-lo em outras direções.</div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">Definamos 5 possíveis comandos:</div>
<ol>
<li>STOP: Pare</li>
<li>LEFT: Vire à esquerda</li>
<li>RIGHT: Vire à direita</li>
<li>REVERSE: Dê marcha à ré</li>
<li>FORWARD: Vá para a frente</li>
</ol>
<br/>O primeiro comando "STOP" é simples de realizar. Todas as entradas da H-Bridge devem estar em LOW, desta forma os motores não se moverão:</div>
<div class="photoset-cell image-cell"></div>
<div class="photoset-cell image-cell"></div>
</div>
</div>
<div class="step-body"><p><span style="color: #993300;">void stopMotor(void)</span> <br/> <span style="color: #993300;">{</span><br/><span style="color: #993300;"> digitalWrite(eneLeftMotor,LOW);</span><br/><span style="color: #993300;"> digitalWrite(eneRightMotor,LOW);</span><br/><span style="color: #993300;"> digitalWrite(leftMotor1,LOW);</span><br/><span style="color: #993300;"> digitalWrite(leftMotor2,LOW);</span><br/><span style="color: #993300;"> digitalWrite(rightMotor1,LOW);</span><br/><span style="color: #993300;"> digitalWrite(rightMotor2,LOW);</span><br/> <span style="color: #993300;">}</span></p>
<pre><br/><br/></pre>
Da mesma forma pensemos em fazer o robô tomar outra direção, digamos que "virar à ESQUERDA". Considere que o robô está indo para a frente, se queremos virar à esquerda podemos pensar em duas situações:<ol>
<li>Parar o motor ESQUERDO, mantendo o motor DIREITO no sentido a frente (Forward): o robô executará uma trajetória de arco para a esquerda</li>
<li>Inverter o sentido do motor ESQUERDO, mantendo o motor DIREITO no sentido a frente (Forward): o robô irá girar sobre seu eixo para a esquerda.</li>
</ol>
<br/>Implementemos o caso 2 acima:</div>
<div class="step-body"></div>
<div class="step-body"></div>
<div class="step-body"><p><span style="color: #993300;">void leftMotor(void)</span> <br/> <span style="color: #993300;">{</span><br/><span style="color: #993300;"> digitalWrite(eneLeftMotor,HIGH);</span><br/><span style="color: #993300;"> digitalWrite(eneRightMotor,HIGH);</span><br/><span style="color: #993300;"> digitalWrite(leftMotor1,LOW);</span><br/><span style="color: #993300;"> digitalWrite(leftMotor2,HIGH);</span><br/><span style="color: #993300;"> digitalWrite(rightMotor1,HIGH);</span><br/><span style="color: #993300;"> digitalWrite(rightMotor2,LOW);</span><br/> <span style="color: #993300;">}</span></p>
<br/>Os demais comandos seguirão a mesma lógica, como ilustra a tabela abiaxo:
<p><img src="https://cdn.instructables.com/FEW/SBPX/J0X5DAHU/FEWSBPXJ0X5DAHU.MEDIUM.jpg" alt="Moving the Robot Around"/></p>
<div id="double-inline-ads" class="clearfix">_____________________________</div>
</div>
</div>
<div class="step-container"><h2 id="step4" class="step-title">4: Completando o HW</h2>
<div id="photoset-S74F895J0X5DB6Y" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FX29AVIJ0X59W9W/"><img src="https://cdn.instructables.com/FX2/9AVI/J0X59W9W/FX29AVIJ0X59W9W.MEDIUM.jpg" alt="Completing the HW"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Siga o diagrama acima e complete o HW de seu Robô.</p>
<p>Você poderá executar alguns testes simples para verificar que seu código está OK. Para isto, introduziremos um "botão" para iniciar o seu robô. Vamos instalá-lo na porta D0 do NodeMCU como mostrado no diagrama elétrico anterior.</p>
<p>Você poderá utilizar o programa <a href="https://github.com/Mjrovai/WiFi-Voice-Controlled-Robot/tree/master/WiFi_Robot_NodeMCU_Android_Voice_Motor_tests">WiFi_Robot_NodeMCU_Android_Voice_Motor_tests</a> que está em meu GitHub, para testar os movimentos de seu robô.</p>
<p>Quando você pressionar o botão, o robô começará a fazer os movimentos definidos no loop (). Os movimentos continuarão até que você pressione "Reset" no NodeMCU. Pressionando o botão "verde" novamente, o ciclo se repetirá.</p>
<p></p>
</div>
</div>
<div class="step-container"><div class="step-container"><div class="step-body"><div id="double-inline-ads" class="clearfix">______________________________________</div>
</div>
</div>
<h2 id="step5" class="step-title">5: Montando o corpo do robô</h2>
<div id="photoset-S4XCWKFJ0X5DDKA" class="photoset"><div class="photoset-row cols-1"></div>
<br/><img class="alignnone size-full wp-image-10723" src="https://mjrobot.files.wordpress.com/2017/04/body-assembly.jpg" alt="body Assembly" width="517" height="483"/></div>
<div class="step-body"><ol>
<li>Use o Kit: Chassis, 2 Rodas, 2 Motores DC, 1 roda solta (coaster)</li>
<li>Solde 2 fios de 10 cm (Vermelho e Preto) em cada polo do motor</li>
<li>Fixe os motores ao chassi como mostrado na foto acima</li>
<li>Monte o <em>coaster</em></li>
<li>Conecte os fios do motor à eletrônica (L293D)</li>
<li>Fixe a bateria de 9V ao chassi</li>
<li>Fixe a bateria de 5V sob o chassi</li>
</ol>
<br/>O robô deverá ficar com essa cara:<p><img class="alignnone size-full wp-image-10725" src="https://mjrobot.files.wordpress.com/2017/04/body-final.jpg" alt="Body Final" width="431" height="324"/></p>
<p></p>
<div class="step-container"><div class="step-body"><div id="double-inline-ads" class="clearfix">__________________________________________________________</div>
<p></p>
</div>
</div>
</div>
</div>
<div class="step-container"><h2 id="step6" class="step-title">6: Conectando o NodeMCU ao seu WiFi local</h2>
<div id="photoset-SWO8J8OJ12EKTGJ" class="photoset"></div>
<div class="step-body"><p>Conectemos o NodeMCU ao WiFi local, verificando seu endereço IP. Para isso, podemos utilizar o programa abaixo:</p>
<p><span style="color: #993300;">#include</span> <br/> <span style="color: #993300;">WiFiClient client;</span><br/> <span style="color: #993300;">WiFiServer server(80);</span><br/> <span style="color: #993300;">const char* ssid = "YOUR SSID";</span><br/> <span style="color: #993300;">const char* password = "YOUR PASSWORD";</span></p>
<p></p>
<p><span style="color: #993300;">void setup()</span> <br/> <span style="color: #993300;">{</span><br/><span style="color: #993300;"> Serial.begin(115200);</span><br/><span style="color: #993300;"> connectWiFi();</span><br/><span style="color: #993300;"> server.begin();</span><br/> <span style="color: #993300;">}</span></p>
<p><br/> <span style="color: #993300;">void loop()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;">}</span><br/></p>
<p></p>
<p><span style="color: #993300;">/* connecting WiFi */</span><br/> <span style="color: #993300;">void connectWiFi()</span><br/> <span style="color: #993300;">{</span><br/><span style="color: #993300;"> Serial.println("Connecting to WIFI");</span><br/><span style="color: #993300;"> WiFi.begin(ssid, password);</span><br/><span style="color: #993300;"> while ((!(WiFi.status() == WL_CONNECTED)))</span><br/><span style="color: #993300;"> {</span><br/><span style="color: #993300;"> delay(300);</span><br/><span style="color: #993300;"> Serial.print("..");</span><br/><span style="color: #993300;"> }</span><br/><span style="color: #993300;"> Serial.println("");</span><br/><span style="color: #993300;"> Serial.println("WiFi connected");</span><br/><span style="color: #993300;"> Serial.println("NodeMCU Local IP is : ");</span><br/><span style="color: #993300;"> Serial.print((WiFi.localIP()));</span><br/> <span style="color: #993300;">}</span></p>
<pre><br/><br/></pre>
<p>No monitor serial voce poderá observar o endereço IP dinâmico designado pelo Modem ao seu NodeMCU.</p>
<p><img src="https://cdn.instructables.com/FNF/N6R2/J0X59W7K/FNFN6R2J0X59W7K.MEDIUM.jpg" alt="Connecting the NodeMCU to Local WiFi"/></p>
<p>Tome nota deste endereço de IP. Precisaremos dele para conectar o App Android.</p>
<p>O código acima poderá ser baixado de meu GitHub:</p>
<p><a href="https://github.com/Mjrovai/Home-Automation-with-Android-and-NodeMCU/tree/master/NodeMCU_Connection_Test_EXT">NodeMCU_Connection_Test_EXT</a></p>
</div>
</div>
<div class="step-container"><div id="double-inline-ads" class="clearfix">______________________________________________________________</div>
<p></p>
<h2 id="step7" class="step-title">7: Completando o código fonte para o NodeMCU</h2>
<div class="step-body"><p>Para que nosso robô se mova, o NodeMCU deverá receber comandos provenientes do dispositivo Android. Para tal, definamos uma variável para receber estes comandos:</p>
<p><span style="color: #993300;">String command ="";</span></p>
<p><br/>Por exemplo, se a aplicação Android enviar como um comando: "<em>forward</em>" (a frente), o robô deverá avançar, invocando-se a função <em>forwardMotor()</em>. Veja abaixo:</p>
<p></p>
<p><span style="color: #993300;">if (command == "forward")</span><br/> <span style="color: #993300;">{</span><br/><span style="color: #993300;"> forwardMotor();</span><br/> <span style="color: #993300;">}</span></p>
<p><br/>O mesmo conceito deverá ser aplicado a todo os demais comandos e funções associadas tal como vimos no item 4:</p>
<ol>
<li>STOP: Pare</li>
<li>LEFT: Vire à esquerda</li>
<li>RIGHT: Vire à direita</li>
<li>REVERSE: Dê marcha à ré</li>
<li>FORWARD: Vá para a frente</li>
</ol>
<p><br/>Baixe o código completo: <a href="https://github.com/Mjrovai/WiFi-Voice-Controlled-Robot/tree/master/WiFi_Robot_NodeMCU_Android_Voice_EXT">WiFi_Robot_NodeMCU_Android_Voice_EXT</a> de meu GitHub.</p>
<p>Entre com as credenciais de sua rede local:</p>
<p><span style="color: #993300;">const char* ssid = "YOUR SSID";</span><br/> <span style="color: #993300;">const char* password = "YOUR PASSWORD";</span></p>
<pre><br/></pre>
<p><br/>Carregue o código em seu NodeMCU e pronto! Você poderá verificar no Monitor Serial se o programa está em execução. Deixe o programa em execução para podermos testar o o aplicativo a ser desenvolvido na próxima etapa.</p>
<p></p>
<div id="double-inline-ads" class="clearfix">_____________________________________________</div>
</div>
</div>
<div class="step-container"><h2 id="step8" class="step-title">8: A App Android : "Designer Tab"</h2>
<div id="photoset-SU0ZZ6QJ12EKXKV" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FLN84G6J0X59X09/"><img src="https://cdn.instructables.com/FLN/84G6/J0X59X09/FLN84G6J0X59X09.MEDIUM.jpg?width=614" alt="The Android App: "/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Usaremos o <em>MIT App Inventor</em> para o desenvolvimento de nossa App Android.</p>
<p><strong>Principais componentes da <em>Screen 1</em> (veja a foto anterior)</strong>:</p>
<ul>
<li>User Interface:<ul>
<li>Input of IP Address<ul>
<li>TextBox named "IP_Address"</li>
</ul>
</li>
<li>5 Command Buttons:<ul>
<li>forward</li>
<li>reverse</li>
<li>right</li>
<li>left</li>
<li>stop</li>
</ul>
</li>
<li>Voice Input Button<ul>
<li>Voice_Input</li>
</ul>
</li>
</ul>
</li>
<li>Non Visible Components:<ul>
<li>Web1</li>
<li>SpeachRecognizer1</li>
<li>TextToSpeach1</li>
</ul>
</li>
<li>Other:<ul>
<li>Text Box:<ul>
<li>Speach_To_Text</li>
</ul>
</li>
<li>Label:<ul>
<li>Comm_Status</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="step-container"><h2 class="step-title"> <img class="alignnone wp-image-10711" src="https://mjrobot.files.wordpress.com/2017/04/screenshot_2017-04-02-14-36-34.png" alt="Screenshot_2017-04-02-14-36-34" width="359" height="574"/></h2>
<div id="double-inline-ads" class="clearfix">_________________________________</div>
<h2 id="step9" class="step-title">9: A App Android: Botões</h2>
<div id="photoset-S7ZAML6J12EKYCN" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/F99JW42J0X5DAJ1/"><img src="https://cdn.instructables.com/F99/JW42/J0X5DAJ1/F99JW42J0X5DAJ1.MEDIUM.jpg" alt="The Android App: Buttons"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Na Tab "Blocks", deveremos criar 5 Botões, um para cada comando. Todos eles seguirão a estrutura dos blocos acima.</p>
<p>Estes blocos serão chamados quando o botão "forward" ("botão com a seta para cima") é pressionado.</p>
<p>Quando você clicar no botão, 3 ações serão executadas:</p>
<ol>
<li>Um comando será enviado no formato: http: / ip_address * / forward</li>
<li>Um "eco" no mesmo formato é esperado</li>
<li>Uma "mensagem" audível será executada pela App: no caso: "forward"</li>
</ol>
<p><br/>* O IP_Address será a que você digitar no seu App. Por exemplo, se o IP address é 10.1.0.3, a mensagem completa seria: http: /10.0.1.3/forward</p>
<blockquote>Você poderá utilizar qualquer mensagem, ou até mesmo deixar a mensagem vazia.</blockquote>
</div>
</div>
<div class="step-container"><div id="double-inline-ads" class="clearfix">__________________________________________________________</div>
<p></p>
<h2 id="step10" class="step-title">10: A App Android: Reconhecimento de voz</h2>
<div id="photoset-SJ55F4VJ12EKZKD" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/F1O0K0YJ0X59W5R/"><img src="https://cdn.instructables.com/F1O/0K0Y/J0X59W5R/F1O0K0YJ0X59W5R.MEDIUM.jpg?width=614" alt="The Android App: Voice Recognition "/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Os blocos acima mostram o código de reconhecimento de voz para o nosso aplicativo.</p>
<p>Note que, para qualquer comando de voz inserido, o resultado será um comando em letras minúsculas. Isso facilitará a descodificação do comando pelo NodeMCU.</p>
<p>Por exemplo, se você deseja mover o robô para a frente, uma palavra ou sentença deverá ser enviada para ser interpretada pelo NodeMCU. No exemplo abaixo, o código reconheceria qualquer uma das palavras: "forward", "frente" ou "a frente ".</p>
<p><br/></p>
<p><br/><span style="color: #000000;">Assim, por exemplo quando digo "frente", a App enviará : http: / 10.0.1.10/frente e o NodeMCU tomará o que é recebido após o "/", a palavra "frente" que será interpretada como um comando do tipo "forward". Com este comando, a função <em>forwardMotor ()</em> será invocada.</span></p>
<div id="double-inline-ads" class="clearfix">_____________________________________________________</div>
</div>
</div>
<div class="step-container"><h2 id="step11" class="step-title">11: A App Android: Manipulação de erros</h2>
<div id="photoset-STXZ26UJ12EL19G" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FSLO0HRJ0X59W4N/"><img src="https://cdn.instructables.com/FSL/O0HR/J0X59W4N/FSLO0HRJ0X59W4N.MEDIUM.jpg" alt="The Android App: Error Manipulation"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Se ocorrer um erro, por exemplo, quando você diz um comando de voz não reconhecido pelo NodeMCU, o bloco acima irá gravar os detalhes do erro na última linha (Comm_Status) do App, conforme mostrado abaixo:</p>
<p><img class="alignnone wp-image-10714" src="https://mjrobot.files.wordpress.com/2017/04/screenshot_2017-04-02-14-36-50.png" alt="Screenshot_2017-04-02-14-36-50" width="346" height="553"/></p>
<p></p>
</div>
</div>
<div class="step-container"><div id="double-inline-ads" class="clearfix">_________________</div>
<p></p>
<h2 id="step12" class="step-title">12: Teste final</h2>
<div id="photoset-S0HOYYNJ12EL1NM" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FCT8VNOJ12EL2A4/"><img src="https://www.instructables.com/files/deriv/FCT/8VNO/J12EL2A4/FCT8VNOJ12EL2A4.MEDIUM.jpg?width=614" alt="Final Test"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Você poderá criar seu aplicativo passo a passo, como mostrado nas etapas anteriores ou fazer o upload do meu projeto completo (.aia) no MIT App Inventor, modificando-o de acordo a suas necessidades. Além disso, caso você não tenha experiência no desenvolvimento de aplicativos para Android, poderá executar o arquivo .apk diretamente em seu dispositivo Android.</p>
<p>Ambos, os arquivos .aia e .apk podem ser baixados de meu GitHub:</p>
<p><a href="https://github.com/Mjrovai/WiFi-Voice-Controlled-Robot/blob/master/MIT%20App%20Inventor/WiFi_Voice_Robot_Ctrl_V2.aia">WiFi_Voice_Robot_Ctrl_V2.aia</a></p>
<p><a href="https://github.com/Mjrovai/WiFi-Voice-Controlled-Robot/blob/master/MIT%20App%20Inventor/WiFi_Voice_Robot_Ctrl_V2.apk">WiFi_Voice_Robot_Ctrl_V2.apk</a></p>
<p>O video abaixo mostra alguns testes de motores utilizando-se do App:</p>
<p></p>
<p><a href="https://youtu.be/K1K1UsZxR5g">https://youtu.be/K1K1UsZxR5g</a></p>
<p></p>
<div id="double-inline-ads" class="clearfix">_____________</div>
</div>
</div>
<div class="step-container"><h2 id="step13" class="step-title">Conclusão</h2>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598220?profile=original" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979598220?profile=RESIZE_320x320" width="300" class="align-full"/></a></p>
<div id="photoset-SWWJROBJ12EL6BO" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><p>Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica, robótica e do IoT!</p>
<p>Verifique o depositário no GitHub para obter os arquivos atualizados:</p>
<p><a href="https://github.com/Mjrovai/WiFi-Voice-Controlled-Robot">WiFi-Voice-Controlled-Robot</a></p>
<p></p>
<p><span>E não deixe de visitar meu site: <a href="https://MJRoBot.org" target="_blank">MJRoBot.org</a> e seguir minha página: </span><a rel="nofollow" href="https://www.facebook.com/mjrobot.org/" target="_blank">MJRoBot.org no Facebook</a></p>
<p>Saludos desde el sur del mundo!</p>
<p>Até o próximo tutorial!</p>
<p>Obrigado</p>
<p>Marcelo</p>
</div>
</div>
</div>
</div>
<div class="step-body"></div>
</div>Controle ativado por voz com Android e NodeMCUtag:labdegaragem.com,2017-03-29:6223006:BlogPost:6044642017-03-29T22:30:00.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="step-container"><div class="step-body"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979600227?profile=original" target="_self"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979600227?profile=RESIZE_1024x1024" width="700"></img></a></p>
<p></p>
<p>Em meu último tutorial: <em><a href="https://mjrobot.org/2017/03/24/quando-o-iot-encontra-a-inteligencia-artificial-automacao-residencial-com-alexa-e-nodemcu/?iframe=true&theme_preview=true" target="_blank">Quando o IoT encontra a Inteligência Artificial: Automação residencial com Alexa…</a></em></p>
</div>
</div>
<div class="step-container"><div class="step-body"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979600227?profile=original" target="_self"><img width="700" src="http://storage.ning.com/topology/rest/1.0/file/get/1979600227?profile=RESIZE_1024x1024" width="700" class="align-full"/></a></p>
<p></p>
<p>Em meu último tutorial: <em><a href="https://mjrobot.org/2017/03/24/quando-o-iot-encontra-a-inteligencia-artificial-automacao-residencial-com-alexa-e-nodemcu/?iframe=true&theme_preview=true" target="_blank">Quando o IoT encontra a Inteligência Artificial: Automação residencial com Alexa e NodeMCU</a>, </em> exploramos como equipamentos ativados por voz como o <em>Amazon Echo-Dot</em> utilizando-se de um serviço da web (como o "Alexa") podem controlar "dispositivos inteligentes" em nossas casas. Neste novo tutorial faremos o mesmo, porém em vez de usar o Alexa desenvolveremos nossa própria App em um smartphone Android controlando, tanto com botões quanto por voz, nossos dispositivos domésticos.</p>
<p>O diagrama de blocos nos dá uma geral do que pretendemos desenvolver:</p>
<p><img class="lazy-img" src="https://www.instructables.com/files/deriv/FYJ/DUXQ/J0SENUNF/FYJDUXQJ0SENUNF.MEDIUM.jpg" alt="Block Diagram.jpg"/></p>
<p>e o filme nos mostra como ficará o projeto final:</p>
<div class="jetpack-video-wrapper"><span class="embed-youtube"><a href="https://youtu.be/bl_stxsm3qs">https://youtu.be/bl_stxsm3qs</a></span></div>
<div class="jetpack-video-wrapper"></div>
</div>
<div id="gpt-ad-native-middle" class="gpt-ad"></div>
</div>
<div class="step-container"><h2 id="step1" class="step-title">1: Lista de materiais (BoM)</h2>
<div class="step-body"><blockquote>Valores em USD, utilizados apenas como referência</blockquote>
<ol>
<li><a href="https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/ref=sr_1_4?ie=UTF8&qid=1489672890&sr=8-4&keywords=NodeMCU+ESP8266-12E">NodeMCU ESP8266-12E</a> ($8.79)</li>
<li><a href="http://a.co/06PTHmB">Mini BreadBoard</a> ($1.00)</li>
<li><a href="http://a.co/2nB8LQs">400-point Experiment Breadboard Breadboard</a> ($ 4.97)</li>
<li><a href="http://a.co/cBkb4HD">4-Channel Relay Module</a> ($8.49)</li>
<li>LEDs (vermelho, amarelo, verde e azul) ($1.00)</li>
<li>4 x Resistor (220 ohm)</li>
<li><a href="http://a.co/gNPxQfa">Male-Female Dupont Cables</a> ($1.00)</li>
<li>Fonte externa DC de 5V ou bateria</li>
</ol>
<br/> ….. e naturalmente um telefone ou tablet Android (qualquer modelo com wifi servirá).</div>
<div id="double-inline-ads" class="clearfix"></div>
</div>
<div class="step-container"><h2 id="step2" class="step-title">2: Conectando o NodeMCU à rede local de WiFi</h2>
<div id="photoset-SYOIYS8J0SELH42" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image">Conectaremos o NodeMCU a rede WiFi local, verificando seu endereço IP. Para isso, usaremos o programa: <a href="https://github.com/Mjrovai/Home-Automation-with-Android-and-NodeMCU/tree/master/NodeMCU_Connection_Test_EXT" target="_blank">Comm test</a></div>
<div class="photoset-item photoset-image"></div>
<div class="photoset-item photoset-image">o qual fará parte do projeto final:</div>
</div>
</div>
</div>
<div class="step-body"><br/> No monitor serial voce poderá ver o IP Address definido por seu Modem ao NodeMCU:<p><img class="alignnone wp-image-10681" src="https://mjrobot.files.wordpress.com/2017/03/serial-monitor-comm-test.jpg" alt="Serial Monitor Comm Test" width="679" height="460"/></p>
<p>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.</p>
</div>
</div>
<div class="step-container"><h2 id="step3" class="step-title">3: Montando o HW</h2>
<div id="photoset-S2RC0I7J0SEMPB0" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/FJX1SXBJ0SELB46/"><img src="https://cdn.instructables.com/FJX/1SXB/J0SELB46/FJX1SXBJ0SELB46.MEDIUM.jpg?width=614" alt="Assembling the HW"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>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:</p>
<p>Conecte as entradas dos relés com os pinos do NodeMCU como mostrado no diagrama e definido no código como mostrado abaixo:</p>
<pre><span style="color: #993300;">int relay1 = 14;</span><br/><span style="color: #993300;">int relay2 = 15;</span><br/><span style="color: #993300;">int relay3 = 3;</span><br/><span style="color: #993300;">
int relay4 = 1;</span></pre>
<p><br/> Nossos dispositivos inteligentes serão simulados pelos LEDs coloridos:</p>
<ul>
<li>relé 1 ==> LED vermelho</li>
<li>relé 2 ==> LED amarelo</li>
<li>relé 3 ==> LED verde</li>
<li>relé 4 ==> LED azul</li>
</ul>
<p><br/> Nosso Android App irá enviar um comando em forma de <em>string, </em> o qual deverá ser interpretado pelo código de maneira a ativar cada um dos relés. Definamos as <em>strings</em> para cada comando:</p>
<ul>
<li>Relé 1:<ul>
<li>Ligar: “r1on”;</li>
<li>Desligar: “r1off”;</li>
</ul>
</li>
<li>Relé 2:<ul>
<li>Ligar: “r2on”;</li>
<li>Desligar: “r2off”;</li>
</ul>
</li>
<li>Relé 3:<ul>
<li>Ligar: “r3on”;</li>
<li>Desligar: “r3off”;</li>
</ul>
</li>
<li>Relé 4:<ul>
<li>Ligar: “r4on”;</li>
<li>Desligar: “r4off”;</li>
</ul>
</li>
</ul>
<p><br/> Definamos uma variável que irá receber os comandos (<em>command</em>) e a lógica associada a mesma:</p>
<pre>String command ="";</pre>
<p><br/> Assim, por exemplo, se o aplicativo Android enviar como um comando: "r1on", o relé 1 (<em>relay1</em>) deverá ser ativado:</p>
<pre><span style="color: #993300;">if (command == "r1on")</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;">digitalWrite(relay1, LOW);</span><br/><span style="color: #993300;">
}</span></pre>
<blockquote>Observe que os relés usados no projeto são ativados com um nível baixo (LOW).</blockquote>
<p><br/> Utilizando <em>alsoif</em>, escreveremos os demais comandos (veja o codigo completo ao final).</p>
<p>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:</p>
<pre><span style="color: #993300;"> if (command == "allon") </span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;">digitalWrite(relay1,LOW);</span><br/><span style="color: #993300;">
digitalWrite(relay2,LOW);</span><br/><span style="color: #993300;">
digitalWrite(relay3,LOW);</span><br/><span style="color: #993300;">
digitalWrite(relay4,LOW);</span><br/><span style="color: #993300;">
}</span></pre>
<p><br/> A mesma lógica deverá ser empregada para o comando "alloff".</p>
<p>Siga o diagrama elétrico acima para concluir a conexão de todo o HW.</p>
<p>Agora faça o download do código completo:</p>
<p><a href="https://github.com/Mjrovai/Home-Automation-with-Android-and-NodeMCU/tree/master/Home_Automation_NodeMCU_Android_Voice_V2_EXT">Home_Automation_NodeMCU_Android_Voice_V2_EXT.ino</a> a partir de meu GitHub.</p>
<p>Entre com as credenciais de sua rede local de WiFi:</p>
<pre>const char* ssid = "YOUR SSID";<br/>const char* password = "YOUR PASSWORD";</pre>
<p><br/> Faça o <em>upload</em> 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.</p>
<blockquote>CUIDADO: Quando fizer o <em>upload</em> do código, desligue a alimentação dos relés para não sobrecarregar o NodeMCU.</blockquote>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step4" class="step-title">4: A App Android : “Designer Tab”</h2>
<div id="photoset-SBX2IMJJ0SEMS2D" class="photoset"><div class="photoset-row cols-1"> Usaremos a aplicação on-line: <em>MIT App Inventor</em> para o desenvolvimento de nossaApp Android:</div>
<div class="photoset-row cols-1"></div>
</div>
<div class="step-body"><p><img class="alignnone size-full wp-image-10565" src="https://mjrobot.files.wordpress.com/2017/03/mit-v2-0.jpg" alt="MIT V2 0" width="678" height="540"/></p>
<p>Componentes Principais da <em>Screen1</em> (veja foto acima)</p>
<ul>
<li>Entrada do endereço IP<ul>
<li>TextBox denominado "IP_Address"</li>
</ul>
</li>
<li>8 botões ON / OFF, um para cada relé:<ul>
<li>Relay_1_ON</li>
<li>Relay_2_OFF</li>
<li>Etc</li>
</ul>
</li>
<li>2 botões ON / OFF para todos os dispositivos:<ul>
<li>All_Devices_ON</li>
<li>All_Devices_OFF</li>
</ul>
</li>
<li>Botão de Entrada de Voz<ul>
<li>Voice_Input</li>
</ul>
</li>
<li>Componentes não visíveis:<ul>
<li>Web1</li>
<li>SpeachRecognizer1</li>
<li>TextToSpeach1</li>
</ul>
</li>
<li>Outros:<ul>
<li>Caixa de texto:<ul>
<li>Speach_To_Text</li>
</ul>
</li>
<li>Label:<ul>
<li>Comm_Status</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><br/> Ao final o aplicativo deverá ficar assim:</p>
<p><img class="alignnone wp-image-10450" src="https://mjrobot.files.wordpress.com/2017/03/screenshot_2017-03-29-16-33-37.png?w=292&h=468" alt="Screenshot_2017-03-29-16-33-37" width="292" height="468"/></p>
</div>
</div>
<div class="step-container"><h2 id="step5" class="step-title">5: A App Android: Botões</h2>
<div class="step-body"><p>Devemos criar na tab <em>Blocks</em>, 10 botões. Todos seguirão a mesma estrutura que os 2 mostrados na foto.</p>
<p><img class="alignnone size-full wp-image-10595" src="https://mjrobot.files.wordpress.com/2017/03/mit-v2-2.jpg" alt="MIT V2 2" width="960" height="180"/></p>
<p>Esses blocos de 2 botões foram criados para:</p>
<ul>
<li>Relay_1_ON. Click</li>
<li>Relay_1_OFF.Click</li>
</ul>
<p><br/> Estas funções são chamadas quando se "clica" em um desses botões. Por exemplo, quando você clica no botão <em>Relay_1_ON</em>, 3 ações serão executadas:</p>
<ol>
<li>Um comando será enviado no formato: http: / ip_address * / r1on</li>
<li>Um "eco" no mesmo formato é esperado devido a "call Web1.Get"</li>
<li>Uma "mensagem" sonora será lida pela App: no caso: "Relé 1 ligado"</li>
</ol>
<p><br/> * O IP_Address será o que você digitar na Tela 1. Utilizando-se o default (<em>10.1.0.3)</em>, a mensagem real seria: <em>http: /10.0.1.3/r1on</em></p>
<blockquote>Voce poderá utilizar qualquer mensagem nesta etapa, ou deixá-la vazia ("") caso não deseje um retorno auditivo.</blockquote>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step6" class="step-title">6: O App Android: Reconhecimento de voz</h2>
<div class="step-body"><p>Os blocos abaixo mostram a construção do código para o reconhecimento de voz de nosso aplicativo:</p>
<p><img class="alignnone size-full wp-image-10615" src="https://mjrobot.files.wordpress.com/2017/03/mit-v2-3.jpg" alt="MIT V2 3" width="960" height="520"/></p>
<p>Note que para qualquer comando de voz, o comando enviado será sempre em minúsculas (uso do bloco de texto <em>downcase</em>). Isso facilitará a decodificação do comando de voz pelo NodeMCU.</p>
<p>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"</p>
<pre><span style="color: #993300;">if (command == "r1on" || command == "ligar 1" || command == "ligar um")</span><br/><span style="color: #993300;">{</span><br/><span style="color: #993300;">digitalWrite(relay1,LOW);</span><br/><span style="color: #993300;">
}</span></pre>
<p><br/> 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.</p>
</div>
</div>
<div class="step-container"><h2 id="step7" class="step-title">7: O App Android: Manipulação de erro</h2>
<div id="photoset-S3UZ0NBJ0SEMWSW" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/F52NDO6J0SELBFS/"><img src="https://cdn.instructables.com/F52/NDO6/J0SELBFS/F52NDO6J0SELBFS.MEDIUM.jpg?width=614" alt="The Android App: Error Manipulation"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Se ocorrer um erro, o bloco acima escreverá os detalhes referente ao mesmo na última linha do App (<em>Comm_Status</em>). Você somente irá ver-lo se ao criar o App usar a opção <em>Responsive</em>.</p>
</div>
</div>
<div class="step-container"><h2 id="step8" class="step-title">8: Testes finais</h2>
<div id="photoset-SM4HR73J0SEMXCQ" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="https://www.instructables.com/file/F4B2JJUJ0SELBRQ/"><img src="https://cdn.instructables.com/F4B/2JJU/J0SELBRQ/F4B2JJUJ0SELBRQ.MEDIUM.jpg?width=614" alt="Final Test"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>Você poderá criar seu aplicativo passo a passo, como mostrado nas etapas anteriores ou utilizar o fonte de meu projeto (.aia) diretamente no MIT App Inventor:</p>
<p><img class="alignnone size-full wp-image-10464" src="https://mjrobot.files.wordpress.com/2017/03/mit-v2-1.jpg?w=840" alt="MIT V2 1"/></p>
<p>Caso você não tenha experiência no desenvolvimento de aplicativos Android, poderá executar o arquivo .apk diretamente em seu dispositivo Android.</p>
<p>Ambos arquivos .aia e .apk poderão ser baixados de meu GitHub:</p>
<p><a href="https://github.com/Mjrovai/Home-Automation-with-Android-and-NodeMCU/blob/master/MIT%20App/Home_Relay_Voice_Ctrl_V2.aia">Home_Relay_Voice_Ctrl_V2.aia</a></p>
<p><a href="https://github.com/Mjrovai/Home-Automation-with-Android-and-NodeMCU/blob/master/MIT%20App/Home_Relay_Voice_Ctrl_V2.apk">Home_Relay_Voice_Ctrl_V2.apk</a></p>
</div>
</div>
<div class="step-container"><h2 id="step9" class="step-title">9: Conclusão</h2>
<div class="step-body"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979602375?profile=original" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979602375?profile=RESIZE_320x320" width="300" class="align-full"/></a></p>
<p>Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica, robótica e do IoT!</p>
<p>Verifique o depositário no GitHub para obter os arquivos atualizados:</p>
<p><a href="https://github.com/Mjrovai/Home-Automation-with-Android-and-NodeMCU">Home-Automation-with-Android-and-NodeMCU</a></p>
<p>Saludos desde el sur del mundo!</p>
<p>Até o próximo tutorial!</p>
<p>Obrigado</p>
<p>Marcelo</p>
</div>
</div>Quando o IoT encontra a Inteligência Artificial: Automação residencial com Alexa e NodeMCUtag:labdegaragem.com,2017-03-24:6223006:BlogPost:6035292017-03-24T16:00:00.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599454?profile=original" target="_self"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599454?profile=original" width="688"></img></a></p>
<p></p>
<p>Exploraremos neste tutorial, como usar a <em>Alexa</em>, um assistente pessoal inteligente desenvolvido pela Amazon Lab126, popularizado pelo Amazon <em>Echo</em> e <em>Echo-Dot</em>.</p>
<p><em>Alexa</em> é 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…</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599454?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/1979599454?profile=original" width="688" class="align-full"/></a></p>
<p></p>
<p>Exploraremos neste tutorial, como usar a <em>Alexa</em>, um assistente pessoal inteligente desenvolvido pela Amazon Lab126, popularizado pelo Amazon <em>Echo</em> e <em>Echo-Dot</em>.</p>
<p><em>Alexa</em> é 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 <em>wake-word</em> (no caso, "Alexa").</p>
<p></p>
<p><a href="https://mjrobot.files.wordpress.com/2017/03/echo-dot-features.jpg" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/echo-dot-features.jpg?width=700" width="700" class="align-full"/></a></p>
<p>No espaço da Domótica (automação residencial), <em>Alexa</em> pode interagir com vários dispositivos diferentes como Philips Hue, Belkin Wemo, SmartThings, etc. Em nosso caso, emularemos dispositivos do tipo <em>WeMo, como estes mostrados abaixo</em> (mas por apenas uma fração de seu preço):</p>
<p><a href="https://mjrobot.files.wordpress.com/2017/03/wemo.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/wemo.png?width=700" width="700" class="align-full"/></a></p>
<p>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 <em>WeMo Switch</em> (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 <em>WeMo App</em>, via rede doméstica WiFi ou rede de telefonia móvel.</p>
<p>O diagrama abaixo mostra o que será desenvolvido em nosso projeto:</p>
<p><a href="https://mjrobot.files.wordpress.com/2017/03/home-automation-block-diagram-v2.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/home-automation-block-diagram-v2.png?width=700" width="700" class="align-full"/></a>E o vídeo abaixo, mostra como ficará o projeto ao final:</p>
<p><a href="https://youtu.be/x3ah_GGHXKg">https://youtu.be/x3ah_GGHXKg</a></p>
<p></p>
<p>.</p>
<div class="embed-frame"><div class="figure youtube"><div class="embed widescreen"><div class="jetpack-video-wrapper"><h3 id="toc-step-1--bill-of-material--bom-0">1: Lista de materiais (<em>BoM</em>)</h3>
<blockquote>Valores referenciais em USD</blockquote>
<ul>
<li><a href="https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/ref=sr_1_4?ie=UTF8&qid=1489672890&sr=8-4&keywords=NodeMCU+ESP8266-12E" rel="nofollow">NodeMCU ESP8266-12E</a> ($8.79)</li>
</ul>
<ul>
<li><a href="http://a.co/eRj3p3f" rel="nofollow">Echo Dot (2nd Generation) - Black</a> ($49.99)</li>
</ul>
<ul>
<li><a href="http://a.co/06PTHmB" rel="nofollow">Mini BreadBoard</a> ($1.00)</li>
</ul>
<ul>
<li><a href="http://a.co/2nB8LQs" rel="nofollow">400-point Experiment Breadboard Breadboard</a> ($ 4.97)</li>
</ul>
<ul>
<li><a href="http://a.co/cBkb4HD" rel="nofollow">4-Channel Relay Module</a> ($8.49)</li>
</ul>
<ul>
<li>LEDs (vermelho e verde) ($1.00)</li>
</ul>
<ul>
<li>2 x Resistor (220 ohm)</li>
</ul>
<ul>
<li><a href="http://a.co/hE6VDp3" rel="nofollow">5V 2 Terminals Electronic Continuous Sound Buzzer</a> ($1.00)</li>
</ul>
<ul>
<li><a href="http://a.co/gNPxQfa" rel="nofollow">Male-Female Dupont Cables</a> ($1.00)</li>
</ul>
<ul>
<li><a href="http://a.co/8wudGyc" rel="nofollow">DC 5V 0.2A Cooling Fan</a> ($4.00)</li>
</ul>
<ul>
<li>Fonte de alimentação externa de 5V DC ou batteria</li>
</ul>
<h3>.</h3>
<h3 id="toc-step-2--wemo-emulation-1">2: Emulando o <em>WeMo Switch</em></h3>
<div class="embed-frame"><div class="figure image_widget"><div class="figcaption embed-figcaption"> <img class="alignnone size-full wp-image-9961" src="https://mjrobot.files.wordpress.com/2017/03/wemo_echo_upnp.png" alt="wemo_echo_upnp" width="697" height="496"/></div>
</div>
</div>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">Os dispositivos <em>WeMo</em> 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 <em>WeMo</em> 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 <em>WeMo</em> através da interface HTTP e emitirá um comando do tipo "SetBinaryState". O <em>WeMo</em> então "obedecerá", retornando uma confirmação via HTTP. O diagrama acima resume a comunicação entre o Echo-Dote o <em>WeMo Switch</em>. 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 .<blockquote>Algumas excelentes fontes de informação sobre o assunto poderão ser encontradas nos links abaixo: <a href="http://hackaday.com/2015/07/16/how-to-make-amazon-echo-control-fake-wemo-devices/" rel="nofollow">HOW TO MAKE AMAZON ECHO CONTROL FAKE WEMO DEVICES</a>, escrito por Rick Osgut <a href="https://medium.com/@monkeytypewritr/amazon-echo-esp8266-iot-a42076daafa5#.g1kt4cjjf" target="_blank" rel="nofollow">Building an IoT power switch with the ESP8266 (and control it with your Amazon Echo!)</a> escrito por Wai Lun <a href="https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch" target="_blank" rel="nofollow">Amazon Alexa + WeMos switch made with Arduino D1 Mini</a> , codigos desenvolvidos por Aruna Tennakoon: <a href="https://github.com/ckuzma/nodemcu-as-arduino/tree/master/Sketches/Alexa/AlexaWemoSwitch" target="_blank" rel="nofollow">Projects using NodeMCU</a>, conjunto de códigos desenvolvidos por Christopher Kuzma</blockquote>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">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: <a href="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU/tree/master/Alexa_LED_Control_V2_EXT" target="_blank" rel="nofollow">Alexa_LED_Control_V2_EXT.ino</a><blockquote>Verifique se você 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: <a href="https://github.com/esp8266/Arduino" target="_blank" rel="nofollow">Arduino core for ESP8266 WiFi chip</a>.</blockquote>
<h3>.</h3>
<h3 id="toc-step-3--creating-our-wemo-device-with-nodemcu-2">3: Criando nosso <em>WeMo Switch</em> com o<em> </em>NodeMCU</h3>
<h3><a href="https://mjrobot.files.wordpress.com/2017/03/alex-and-nodemcu.jpg" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/alex-and-nodemcu.jpg?width=700" width="700" class="align-full"/></a></h3>
Para o nosso primeiro teste, conectemos um LED ao NodeMCU pino D1 como mostrado no diagrama abaixo:<br />
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"><a href="https://mjrobot.files.wordpress.com/2017/03/nodemcu-and-led.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/nodemcu-and-led.png?width=375" width="375" class="align-full"/></a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Abra o arquivo <em><a href="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU/tree/master/Alexa_LED_Control_V2_EXT" target="_blank">Alexa_LED_Control_V2_EXT.ino</a></em> , o qual você baixou de meu GitHub e entre com suas credenciais de rede:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;"><span class="font-size-2">const char* ssid = "YOUR SSID";<br/>const char* password = "YOUR PASSWORD";</span><br/></span></pre>
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:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;"><span class="font-size-2">String device_name = "lights"; <br/>int relayPin = D1; </span><br/></span></pre>
No meu caso, o dispositivo será denominado "<strong>lights</strong>". 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.</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><a href="https://mjrobot.files.wordpress.com/2017/03/serial-monitor1.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/serial-monitor1.png?width=700" width="700" class="align-full"/></a><blockquote>Estarei levando em consideração que voce já tenha o Echo-Dot instalado em sua rede., bem como o Alexa App em 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.</blockquote>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">Agora, necessitamos que a Alexa encontre seu dispositivo. Existem dois métodos para isso:<ul>
<li>Utilizando o aplicativo Alexa no smartphone como mostrado nas fotos abaixo. Em nosso caso, a Alexa encontrará "1 Smart Home device": <strong>lights</strong> WeMo Switch.</li>
</ul>
<p></p>
<a href="https://mjrobot.files.wordpress.com/2017/03/alexa-app.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/alexa-app.png?width=700" width="700" class="align-full"/></a><br />
<ul>
<li style="padding-left: 30px;">Pedindo diretamente à Alexa através de um comando de voz, como por exemplo: "<em>Alexa, Find connected devices</em>" como poderá ser visto no vídeo abaixo:</li>
</ul>
<div class="embed-frame"><div class="figure youtube"><div class="embed widescreen">youtube <a href="https://www.youtube.com/watch?v=x8PqB6X6Sg0?rel=0">https://www.youtube.com/watch?v=x8PqB6X6Sg0?rel=0</a></div>
<div class="embed widescreen"></div>
<div class="embed widescreen"></div>
<div class="embed widescreen">Uma vez que a Alexa descobriu seu dispositivo, você poderá usar comandos de voz para o acionamento do dispositivo como mostrado abaixo:</div>
</div>
</div>
<div class="embed-frame"><div class="figure youtube"><div class="figcaption embed-figcaption"></div>
<div class="embed widescreen">youtube <a href="https://www.youtube.com/watch?v=A604IrQLjUU?rel=0">https://www.youtube.com/watch?v=A604IrQLjUU?rel=0</a></div>
<div class="embed widescreen"></div>
</div>
</div>
<h3>.</h3>
<h3 id="toc-step-4--working-with-multiple-devices-3">Step 4: Acionando vários dispositivos ao mesmo tempo</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="figcaption embed-figcaption"><a href="https://mjrobot.files.wordpress.com/2017/03/img_1224.jpg" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/img_1224.jpg?width=700" width="700" class="align-full"/></a></div>
<div class="figcaption embed-figcaption"></div>
<div class="figcaption embed-figcaption">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).</div>
</div>
</div>
Usaremos um módulo de relé de 4 canais para controlar 2 lâmpadas e 2 tomadas.<br />
<blockquote>Esta parte do projeto foi baseada em grande parte no tutorial de Charles Gantt, <a href="https://www.instructables.com/id/How-To-DIY-Home-Automation-With-NodeMCU-and-Amazon/" target="_blank" rel="nofollow">How To: DIY Home Automation With NodeMCU and Amazon Alexa</a>.</blockquote>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">Siga as instruções abaixo: Conecte as entradas dos relés com os pinos do NodeMCU conforme descrito abaixo:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;" class="font-size-2">int relayOne = 14; // NodeMCU pin D5<br/>int relayTwo = 15; // NodeMCU pin D8<br/>int relayThree = 3; // NodeMCU pin RX<br/>int relayFour = 1; // NodeMCU pin TX</span></pre>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">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:<ul>
<li>Light One</li>
</ul>
<ul>
<li>Light Two</li>
</ul>
<ul>
<li>Outlet One</li>
</ul>
<ul>
<li>Outlet Two</li>
</ul>
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:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;" class="font-size-2">lightOne = new Switch("Light One", 80, lightOneOn, lightOneOff);<br/>lightTwo = new Switch("Light Two", 81, lightTwoOn, lightTwoOff);<br/>outletOne = new Switch("Outlet One", 82, outletOneOn, outletOneOff);<br/>outletTwo = new Switch("Outlet Two", 83, outletTwoOn, outletTwoOff);</span><br/><br/></pre>
Agora, você deve definir as 2 funções relacionadas a cada condição do dispositivo: Para as lâmpadas:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;">void lightOneOn() {<br/> Serial.print("Switch 1 turn on ...");<br/> digitalWrite(relayOne, LOW); // sets relayOne on}
<br/><br/>void lightOneOff() {
Serial.print("Switch 1 turn off ...");<br />
digitalWrite(relayOne, HIGH); // sets relayOne off<br />
}<br />
<br />
void lightTwoOn() {<br />
Serial.print("Switch 2 turn on ...");<br />
digitalWrite(relayThree, LOW); // sets relayTwo on<br />
}<br />
<br />
void lightTwoOff() {<br />
Serial.print("Switch 2 turn off ...");<br />
digitalWrite(relayThree, HIGH); // sets relayTwo Off<br />
}</span></pre>
<span style="color: #993300;">E para as tomadas:</span><br />
<pre><span style="color: #993300;">void outletOneOn() { Serial.print("Socket 1 turn on ..."); digitalWrite(relayFour, LOW); // sets relayThree on
}<br />
<br />
void outletOneOff() {<br />
Serial.print("Socket 1 turn off ...");<br />
digitalWrite(relayFour, HIGH); // sets relayThree off<br />
}<br />
<br />
void outletTwoOn() {<br />
Serial.print("Socket 2 turn on ...");<br />
digitalWrite(relayTwo, LOW); // sets relayFour on<br />
}<br />
<br />
void outletTwoOff() {<br />
Serial.print("Socket 2 turn off ...");<br />
digitalWrite(relayTwo, HIGH); // sets relayFour off<br />
}</span><br/><br/></pre>
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 .<br />
<ul>
<li>Como "Light 1", usarei um LED vermelho</li>
</ul>
<ul>
<li>Como "Light 2", usarei um LED verde</li>
</ul>
<ul>
<li>Como "Outlet 2", usarei um pequeno buzzer (pense em um rádio, aparelho de som...)</li>
</ul>
<ul>
<li>Como "Outlet 1", usarei um pequeno ventilador</li>
</ul>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">Abaixo o diagrama elétrico com as conexões: <a href="https://mjrobot.files.wordpress.com/2017/03/home-automation-electric-diagram.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/home-automation-electric-diagram.png?width=700" width="700" class="align-full"/></a> Com o HW pronto, baixe o código de meu GitHub: <a href="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU/tree/master/NODEMCU_ALEXA_WeMos_4X_Serial_Monitor_EXT" target="_blank" rel="nofollow">NODEMCU_ALEXA_WeMos_4X_Serial_Monitor_EXT.ino</a> Entre com suas credenciais de rede:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;">const char* ssid = "YOUR SSID";<br/>const char* password = "YOUR PASSWORD";</span><br/><br/></pre>
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:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><div class="embed-frame"><div class="figure youtube"><div class="embed widescreen">youtube <a href="https://www.youtube.com/watch?v=PZUHCDCEuFA?rel=0">https://www.youtube.com/watch?v=PZUHCDCEuFA?rel=0</a></div>
<div class="embed widescreen"></div>
</div>
</div>
<h3>.</h3>
<h3 id="toc-step-5--home-automation-4">5: Aplicação em Domótica (Automação Residencial)</h3>
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:<br />
<ul>
<li>Quarto ("Bed Room")</li>
</ul>
<ul>
<li>Sala ("Living Room")</li>
</ul>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">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:<ul>
<li><a href="https://mjrobot.files.wordpress.com/2017/03/img_9708.jpg" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/img_9708.jpg?width=178" width="178" class="align-full"/></a>Quarto (<em>Bed Room</em>)<ul>
<li>Light 2</li>
<li>Outlet 1 (Ventilador)</li>
</ul>
</li>
<li>Sala (<em>Living Room)</em><ul>
<li>Light1</li>
<li>Outlet 2 (Buzzer)</li>
</ul>
</li>
</ul>
<div class="embed-frame"></div>
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:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><strong>1. Definição das "Switches":</strong></div>
<div class="jetpack-video-wrapper"><pre><br/><span style="color: #993300;">Switch *allDevices = NULL;<br/>Switch *bedRoom = NULL;<br/>Switch *livingRoom = NULL;</span><br/><br/></pre>
<strong>2. Declaração dos "callbacks" para os novos grupos de dispositivos:</strong></div>
<div class="jetpack-video-wrapper"><pre><br/><span style="color: #993300;">void allDevicesOn();<br/>void allDevicesOff();<br/>void bedRoomOn();<br/>void bedRoomOff();<br/>void livingRoomOn();<br/>void livingRoomOff();</span><br/><br/></pre>
3. 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):</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;">allDevices = new Switch("All Devices", 84, allDevicesOn, allDevicesOff);<br/>bedRoom = new Switch("Bed Room", 85, bedRoomOn, bedRoomOff);<br/>livingRoom = new Switch("Living Room", 86, livingRoomOn, livingRoomOff);</span><br/><br/></pre>
4. Adicionando "Switches upnp Broadcast Responder" ao setup():</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;">upnpBroadcastResponder.addDevice(*allDevices);<br/>upnpBroadcastResponder.addDevice(*bedRoom);<br/>upnpBroadcastResponder.addDevice(*livingRoom);</span><br/><br/></pre>
5. Adicionando as linhas ao loop():</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;">allDevices->serverLoop();<br/>bedRoom->serverLoop();<br/>livingRoom->serverLoop();</span><br/><br/></pre>
6. 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:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><pre><span style="color: #993300;">void allDevicesOn() { <br/> Serial.print("All Devices turn on ...");
digitalWrite(relayOne, LOW); // sets relay1 on<br />
digitalWrite(relayTwo, LOW); // sets relay2 on<br />
digitalWrite(relayThree, LOW); // sets relay3 on<br />
digitalWrite(relayFour, LOW); // sets relay4 on<br />
}<br />
<br />
void allDevicesOff() <br />
{<br />
Serial.print("All Devices turn off ...");<br />
digitalWrite(relayOne, HIGH); // sets relay1 off<br />
digitalWrite(relayTwo, HIGH); // sets relay2 off<br />
digitalWrite(relayThree, HIGH); // sets relay3 off<br />
digitalWrite(relayFour, HIGH); // sets relay4 off<br />
}<br />
<br />
void bedRoomOn() <br />
{<br />
Serial.print("Bed Room turn on ...");<br />
digitalWrite(relayThree, LOW); // sets relay3 on<br />
digitalWrite(relayFour, LOW); // sets relay4 on<br />
}<br />
<br />
void bedRoomOff() <br />
{<br />
Serial.print("Bed Room turn off ...");<br />
digitalWrite(relayThree, HIGH); // sets relay3 off<br />
digitalWrite(relayFour, HIGH); // sets relay4 off<br />
}<br />
<br />
void livingRoomOn() <br />
{<br />
Serial.print("Living Room turn on ...");<br />
digitalWrite(relayOne, LOW); // sets relay1 on<br />
digitalWrite(relayTwo, LOW); // sets relay2 on<br />
}<br />
<br />
void livingRoomOff() <br />
{<br />
Serial.print("Living Room turn off ...");<br />
digitalWrite(relayOne, HIGH); // sets relay1 off<br />
digitalWrite(relayTwo, HIGH); // sets relay2 off<br />
}<br/><br/></span></pre>
<blockquote>Este procedimento de 6 passos poderá ser utilizado para qualquer comando, dispositivo ou grupo de dispositivos que você deseja adicionar ao seu projeto.</blockquote>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">Você poderá baixar o código completo desta etapa. desde meu GitHub: <a href="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU/tree/master/NODEMCU_ALEXA_WeMos_4X_V2_EXT" rel="nofollow">NODEMCU_ALEXA_WeMos_4X_V2_EXT</a></div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">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 <em>Alexa App</em>. Em ambos casos, o resultado poderá ser verificado no aplicativo como mostrado abaixo. Sete dispositivos ("WeMo Switches") deverão ser encontrados agora pela Alexa:<ul>
<li><a href="https://mjrobot.files.wordpress.com/2017/03/img_1261.png" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/03/img_1261.png?width=209" width="209" class="align-full"/></a>Living Room</li>
</ul>
<ul>
<li>Bed Room</li>
</ul>
<ul>
<li>All Devices</li>
</ul>
<ul>
<li>Outlet One</li>
</ul>
<ul>
<li>Outlet Two</li>
</ul>
<ul>
<li>Light One</li>
</ul>
<ul>
<li>Light Two</li>
</ul>
<div class="embed-frame"></div>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">O vídeo abaixo mostra como nosso projeto completo de Automação Residencial funcionará:</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><div class="embed-frame"><div class="figure youtube"><div class="embed widescreen">youtube <a href="https://www.youtube.com/watch?v=x3ah_GGHXKg?rel=0">https://www.youtube.com/watch?v=x3ah_GGHXKg?rel=0</a></div>
<div class="embed widescreen"></div>
</div>
</div>
<h3>.</h3>
<h3 id="toc-step-6--conclusion-5">6: Conclusão</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="figcaption embed-figcaption"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599449?profile=original" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599449?profile=RESIZE_480x480" width="400" class="align-full"/></a></div>
<div class="figcaption embed-figcaption"></div>
<div class="figcaption embed-figcaption">Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da electrónica, robótica e do IoT!</div>
<div class="figcaption embed-figcaption"></div>
<div class="figcaption embed-figcaption">Verifique o depositário no GitHub para obter os arquivos atualizados:</div>
</div>
</div>
<a href="https://github.com/Mjrovai/Home-Automation-with-Alexa-and-NodeMCU" rel="nofollow">Home-Automation-with-Alexa-and-NodeMCU</a><br />
<p class="p1"></p>
<p class="p1">E não deixe de visitar e seguir minha página: <a href="https://www.facebook.com/mjrobot.org/" target="_blank">MJRoBot.org no Facebook</a></p>
</div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><p>"Saludos desde el sur del mundo"!</p>
<p>Nos vemos em meu próximo post!</p>
<p>Obrigado e um abraço</p>
<p>Marcelo</p>
</div>
</div>
<div class="embed widescreen"></div>
</div>
</div>IoT feito simples: Estação meteorológica doméstica com NodeMCU e OLEDtag:labdegaragem.com,2017-03-17:6223006:BlogPost:6025882017-03-17T19:30:53.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979600599?profile=original" target="_self"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979600599?profile=RESIZE_1024x1024" width="650"></img></a></p>
<p></p>
<p>Continuemos nossa exploração pelo mundo do IoT, nas asas do NodeMCU! Neste tutorial, desenvolveremos uma estação meteorológica doméstica, onde se exibirá informações tais como temperatura e condições climáticas, tanto para o dia corrente quanto para os próximos 3 dias. Nossa estação também exibirá informações internas da casa, como temperatura e umidade…</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979600599?profile=original" target="_self"><img width="650" src="http://storage.ning.com/topology/rest/1.0/file/get/1979600599?profile=RESIZE_1024x1024" width="650" class="align-full"/></a></p>
<p></p>
<p>Continuemos nossa exploração pelo mundo do IoT, nas asas do NodeMCU! Neste tutorial, desenvolveremos uma estação meteorológica doméstica, onde se exibirá informações tais como temperatura e condições climáticas, tanto para o dia corrente quanto para os próximos 3 dias. Nossa estação também exibirá informações internas da casa, como temperatura e umidade relativa do ar. O diagrama em blocos abaixo, nos dá uma visão geral sobre o projeto: <img src="https://hackster.imgix.net/uploads/attachments/274371/FGI85M2J08EIS8J.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<p></p>
<p>O vídeo abaixo mostra como ficará o projeto final:</p>
<div class="embed-frame"><div class="figure youtube"><div class="embed widescreen"><div class="jetpack-video-wrapper"><span class="embed-youtube"><a href="https://youtu.be/n2SL7BvOZeg">https://youtu.be/n2SL7BvOZeg</a></span></div>
<div class="jetpack-video-wrapper"></div>
<br/> <br/>
<div class="jetpack-video-wrapper">E o tutorial completo com diagramas, códigos fonte e explicações, está disponível em meu Blog: </div>
<div class="jetpack-video-wrapper"><a href="https://mjrobot.org/2017/03/17/iot-feito-simples-estacao-meteorologica-domestica-com-nodemcu-e-oled/" target="_blank">IoT feito simples: Estação meteorológica doméstica com NodeMCU e OLED</a><a rel="nofollow" href="https://mjrobot.org/2017/02/21/ardufarmbot-2-sistema-automatico-para-irrigacao-e-calor-agora-com-o-nodemcu-e-blynk/" target="_blank"><br/></a></div>
<div class="jetpack-video-wrapper"><div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"></div>
<div class="image slick-slide slick-active"><a width="400" href="http://storage.ning.com/topology/rest/1.0/file/get/1979600921?profile=RESIZE_480x480" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979600921?profile=RESIZE_480x480" class="align-center"/></a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="p1">Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da eletrônica e do IoT! E não deixe de visitar e seguir minha página: <a rel="nofollow" href="https://www.facebook.com/mjrobot.org/" target="_blank">MJRoBot.org no Facebook</a></p>
<p></p>
<p>"Saludos desde el sur del mundo"!</p>
<p>Nos vemos em meu próximo post!</p>
<p>Obrigado e um abraço</p>
<p>Marcelo</p>
</div>
<div class="jetpack-video-wrapper"></div>
</div>
</div>
</div>Saindo do forno:"ArduFarmBot, o livro!"tag:labdegaragem.com,2017-03-13:6223006:BlogPost:6015192017-03-13T00:26:21.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="_5pbx userContent" id="js_18vk"><div class="text_exposed_root text_exposed" id="id_58c5e256b6c6f4d12106819"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979601151?profile=original" target="_self"><img class="align-center" src="http://storage.ning.com/topology/rest/1.0/file/get/1979601151?profile=RESIZE_320x320" width="300"></img></a></p>
<p></p>
<p>Pessoal, está saindo do forno o primeiro livro da série "Tutoriais MJRoBot", o "ArduFarmBot". O livro pode ser adquirido na loja do Kindle na Amazom.com.br, mas os amigos aqui do Garagem podem baixar-lo gratis no link abaixo:…</p>
<p></p>
</div>
</div>
<div class="_5pbx userContent" id="js_18vk"><div id="id_58c5e256b6c6f4d12106819" class="text_exposed_root text_exposed"><p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979601151?profile=original" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979601151?profile=RESIZE_320x320" width="300" class="align-center"/></a></p>
<p></p>
<p>Pessoal, está saindo do forno o primeiro livro da série "Tutoriais MJRoBot", o "ArduFarmBot". O livro pode ser adquirido na loja do Kindle na Amazom.com.br, mas os amigos aqui do Garagem podem baixar-lo gratis no link abaixo:</p>
<p><a href="https://www.dropbox.com/s/odh5bfyewa31o0k/ArduFarmBot_Portugues_Ed2_V_Final_2.pdf?dl=0" target="_blank">Link para baixar o livro em PDF</a></p>
<p>Se gostarem por favor, divulguem o livro e principalmente deixem um comentário na página da Amazon.com.br:</p>
<p><a href="http://a.co/etXnWZL" target="_blank">Link para a loja da Amazon.com.br</a></p>
<p>Caso encontrem erros, podem me escrever aqui no Garagem, que procurarei corrigir nas próximas edições.</p>
<p>O livro usa o controlador eletrônico "ArduFarmBot" como base para o aprendizado de como se trabalhar tanto em HW quanto em SW, com: a) Displays do tipo LCD e OLED; b) LEDs e botões; c) Acionamento de bombas e lâmpadas via relés e d) Leitura de sensores tais como: DHT22 (temperatura e umidade rela<span class="text_exposed_show">tiva do ar), DS18B20 (temperatura do solo), YL69 (umidade do solo) e LDR (luminosidade).</span></p>
<div class="text_exposed_show"><p>Todas as principais etapas dos projetos são detalhadamente documentadas através de textos explicativos, diagramas de blocos, fotos coloridas de alta resolução, diagramas elétricos utilizando-se do aplicativo "Fritzing", códigos completos armazenados no "GitHub" e vídeos do "YouTube".</p>
<p>No livro, são desenvolvidas duas versões do controlador eletrônico "ArduFarmBot", que a partir da captura de dados provenientes de uma horta de tomates, tais como temperatura do ar e solo, umidade relativa do ar, umidade do solo e luminosidade, decidem autonomamente a quantidade certa (e quando) uma plantação deve receber calor e água. O ArduFarmBot também permite a intervenção manual, tanto em forma local quanto remota via Internet, a fim de controlar o acionamento de uma bomba de água e de uma lâmpada elétrica, esta última para ser usada na geração de calor para as plantas.</p>
<p>O livro está dividido em 3 partes.</p>
<p>Na primeira parte, a partir do "Arduino Nano" de desenvolve uma versão tanto manual operada por botões, quanto automática do "ArduFarmBot".</p>
<p>Na segunda parte, se aprofunda no projeto da automação e introduz a operação remota através da criação de uma página na internet. O "ESP8266-01" é utilizado para a conexão “Wifi”, enviando dados para o serviço especializado em IoT, "<a href="https://l.facebook.com/l.php?u=http%3A%2F%2FThingSpeak.com%2F&h=ATPGoFwTHMqgdLleZnIzhLCJiQndNqHyAN_nV-aM69rLhFTYoCh4RmPMnxfwVIkd4G94bIjO1TL91UGFJV-8-Tg00uED-AAF0hUyx4DzDa04uYVqXlGNf1SQdLHWFRXdaxaD7lfWJg&enc=AZNvrjtsvq316ZK_pmiptVTWFNFgIiM9CXAaW4pBvBYXQyqB2Zpjg3Lre2slPNuo04hzqaWKQMnpgfhq2Uyd9_WytSFA4gqova1OQ63bLymYFuv_OXgRWapFc8hxZX6NkZYoBEaNTEPxNd42PzitsPiN712vo7W4Au9U7HOzVm4CAF_Z3-M0TU6E4XpaE2wfEK12kowPuFjlfq_Z1kJ-YhNy&s=1" target="_blank" rel="nofollow noopener">ThingSpeak.com</a>".</p>
<p>Na terceira parte, uma segunda versão do "ArduFarmBot" é desenvolvida, introduzindo o "NodeMCU ESP8266-12E", um poderoso e versátil dispositivo para projetos em IoT, que substitui de forma integrada tanto o "Arduino Nano" quanto o "ESP8266-01", utilizados nas partes anteriores do livro. Nesta última, se explora também uma nova plataforma de serviços do universo IoT, o "Blynk".</p>
<p>Abração</p>
<p>Marcelo</p>
<p></p>
<p></p>
</div>
</div>
</div>“ArduFarmBot 2” – Sistema automático para irrigação e calor, agora com o NodeMCU e Blynktag:labdegaragem.com,2017-02-21:6223006:BlogPost:5977102017-02-21T22:31:20.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p><a href="https://mjrobot.files.wordpress.com/2017/02/img_0724-1.jpg?w=768&h=1&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2017/02/img_0724-1.jpg?w=768&h=1&crop=1&width=700" width="700"></img></a></p>
<p>Algum tempo atrás, desenvolvi o projeto de um sistema de jardinagem totalmente automatizado: “<a href="https://mjrobot.org/2016/09/02/ardufarmbot-controlando-um-tomateiro-com-a-ajuda-de-um-arduino-e-internet-das-coisas-iot/" target="_blank">ArduFarmBot: Controlando um tomateiro com a ajuda de um Arduino e Internet das coisas (IoT)</a>“. As principais…</p>
<p><a href="https://mjrobot.files.wordpress.com/2017/02/img_0724-1.jpg?w=768&h=1&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/02/img_0724-1.jpg?w=768&h=1&crop=1&width=700" width="700" class="align-full"/></a></p>
<p>Algum tempo atrás, desenvolvi o projeto de um sistema de jardinagem totalmente automatizado: “<a href="https://mjrobot.org/2016/09/02/ardufarmbot-controlando-um-tomateiro-com-a-ajuda-de-um-arduino-e-internet-das-coisas-iot/" target="_blank">ArduFarmBot: Controlando um tomateiro com a ajuda de um Arduino e Internet das coisas (IoT)</a>“. As principais especificações originais serão mantidas nesta nova versão, o ArduFarmBot 2, porém agora o projeto será baseado nas plataformas de IoT: <em><strong>NodeMCU ESP8266 e BLYNK.</strong></em></p>
<p>Com base em dados coletados de uma plantação qualquer tais como, temperatura e umidade, tanto do ar quanto do solo, o ArduFarmBot 2 decidirá a quantidade certa (e quando) o plantio 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.</p>
<p>Em suma, o sistema deve receber como</p>
<p><strong>A. ENTRADA</strong></p>
<p><em>Sensores:</em></p>
<ul>
<li>Temperatura do ar</li>
<li>Umidade Relativa ao Ar</li>
<li>Temperatura do solo</li>
<li>Umidade do solo</li>
</ul>
<p><em>Botões:</em></p>
<ul>
<li>Bomba ON / OFF</li>
<li>Lâmpada ON / OFF</li>
</ul>
<p></p>
<p><strong>B. SAÍDA:</strong></p>
<p><em>Atuadores:</em></p>
<ul>
<li>Relé para controle da bomba</li>
<li>Relé para controle de lâmpada</li>
</ul>
<p><em>Mensagens automáticas devem ser enviadas na ocorrência de eventos, tais como:</em></p>
<ul>
<li>Bomba LIGADA</li>
<li>Lâmpada LIGADA</li>
<li>Sistema off-line</li>
</ul>
<p><em>Exibição de dados</em></p>
<ul>
<li>Todos os dados analógicos e digitais devem estar disponíveis para avaliação imediata</li>
</ul>
<p><em>Armazenamento de dados</em></p>
<ul>
<li>Dados históricos devem ser armazenados remotamente</li>
</ul>
<p></p>
<p>O diagrama de blocos abaixo mostra os principais componentes do projeto.</p>
<p></p>
<p></p>
<p><a href="https://mjrobot.files.wordpress.com/2017/02/ardufarmbot2_block_diagram.png?w=768" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/02/ardufarmbot2_block_diagram.png?w=768&width=700" width="700" class="align-full"/></a></p>
<p></p>
<p>O tutorial completo poderá ser encontrado em meu Blog: <a href="https://mjrobot.org/2017/02/21/ardufarmbot-2-sistema-automatico-para-irrigacao-e-calor-agora-com-o-nodemcu-e-blynk/" target="_blank">“ArduFarmBot 2” – Sistema automático para irrigação e calor, agora com o NodeMCU e Blynk</a></p>
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"><a class="embed-img"><img class=" aligncenter" src="https://hackster.imgix.net/uploads/attachments/262257/tmp_file_CVl2gnDnmn.tmp_file?auto=compress%2Cformat&w=680&h=510&fit=max"/></a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="p1">Como sempre, espero que este projecto possa ajudar outros a encontrarem o seu caminho no emocionante mundo da eletrônica e do IoT! E não deixe de visitar e seguir minha página: <a href="https://www.facebook.com/mjrobot.org/" target="_blank">MJRoBot.org no Facebook</a></p>
<p></p>
<p>Saludos desde el sur del mundo!</p>
<p>Nos vemos em meu próximo post!</p>
<p>Obrigado e um abraço</p>
<p>Marcelo</p>
<p></p>O IoT feito simples: Monitorando a temperatura desde qualquer lugartag:labdegaragem.com,2017-01-06:6223006:BlogPost:5886722017-01-06T19:32:30.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<a href="https://mjrobot.files.wordpress.com/2017/01/fzxen7jixkpyn9v-large.jpg?w=530&h=1&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2017/01/fzxen7jixkpyn9v-large.jpg?w=530&h=1&crop=1"></img></a><br />
<br />
<p>É incrível como hoje em dia podemos montar rapidamente um projeto de IoT utilizando-se apenas de um "chip" de uns poucos dólares e um aplicativo carregado em seu smartphone.</p>
<p>Neste tutorial também aprenderemos sobre um sensor digital de temperatura confiável e muito fácil de usar, o DS18B20.</p>
<p><img src="https://hackster.imgix.net/uploads/attachments/248061/FPSBH48IXGFU17X.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"></img></p>
<p>Como mostrado no diagrama de bloco…</p>
<a href="https://mjrobot.files.wordpress.com/2017/01/fzxen7jixkpyn9v-large.jpg?w=530&h=1&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2017/01/fzxen7jixkpyn9v-large.jpg?w=530&h=1&crop=1" class="align-full"/></a><br />
<br />
<p>É incrível como hoje em dia podemos montar rapidamente um projeto de IoT utilizando-se apenas de um "chip" de uns poucos dólares e um aplicativo carregado em seu smartphone.</p>
<p>Neste tutorial também aprenderemos sobre um sensor digital de temperatura confiável e muito fácil de usar, o DS18B20.</p>
<p><img src="https://hackster.imgix.net/uploads/attachments/248061/FPSBH48IXGFU17X.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<p>Como mostrado no diagrama de bloco acima, os dados coletados pelo sensor serão enviados à Internet com a ajuda de um NodeMCU ESP8266-E e monitorados em um celular ou tablet utilizando-se o aplicativo Blynk.</p>
<p></p>
<p></p>
<h3 id="toc-step-1--bill-of-material-0">1: Lista de Material</h3>
<ul>
<li><a href="https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/ref=sr_1_fkmr2_3?ie=UTF8&qid=1483559586&sr=8-3-fkmr2&keywords=NodeMCU+ESP+12-E" target="_blank" rel="nofollow">NodeMCU ESP 12-E</a></li>
</ul>
<ul>
<li><a href="https://www.amazon.com/dp/B00Q9YBIJI?psc=1" target="_blank" rel="nofollow">DS18B20 Temperature Sensor</a></li>
</ul>
<ul>
<li>Resistor 4.7K Ohms</li>
</ul>
<p></p>
<p></p>
<h3 id="toc-step-2--ds18b20-temperature-sensor-1">2: DS18B20 Sensor Digital de Temperatura</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"><a class="embed-img"><img class=" alignleft" src="https://hackster.imgix.net/uploads/attachments/248062/FG1WQHAIXGFTY0F.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max" width="258" height="258"/></a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Usaremos neste tutorial, uma versão à prova de agua do sensor DS18B20. Esta configuração é muito útil para se medir temperaturas de maneira remota em condições de umidade, por exemplo em coleta de dados de solo. O sensor é isolado e pode ser usado em até 125oC (Adafrut não recomenda usá-lo acima dos 100oC devido a a capa de PVC utilizada em seu cabo).<br />
<br />
O DS18B20 é um sensor do tipo digital, o que o torna util para uso mesmo em longas distâncias! Estes sensores digitais de temperatura "1-Wire" são bastante precisos (± 0,5 ° C em grande parte da faixa) e podem fornecer até 12 bits de precisão a partir do conversor digital-analógico integrado. Eles funcionam muito bem com micro-controladores como o NodeMCU ou Arduino, utilizando-se de apenas um único pino digital. Você poderá até mesmo conectar-lo a vários outros sensores no mesmo pino, pois cada um dos sensores possui um único ID de 64 bits gravado de fábrica para diferenciá-los.<br />
<br />
O sensor funciona de 3.0 a 5.0V, o que significa que ele pode ser alimentado diretamente a partir de um dos pinos de 3.3V do NodeMCU.<br />
O Sensor possui 3 fios:<br />
<ul>
<li>Preto: GND</li>
</ul>
<ul>
<li>Vermelho: VCC</li>
</ul>
<ul>
<li>Amarelo: 1-Wire Data</li>
</ul>
No link ao lado, voce encontrará a especificação completa: <a href="https://cdn-shop.adafruit.com/datasheets/DS18B20.pdf" target="_blank" rel="nofollow">DS18B20 Datasheet</a><br />
<div class="embed-frame"></div>
<p></p>
<p></p>
<h3 id="toc-step-3--connecting-the-sensor-to-nodemcu-2">3: Conectando o sensor ao NodeMCU</h3>
Conecte os 3 fios do sensor NodeMCU como mostrado no diagrama abaixo:<img src="https://hackster.imgix.net/uploads/attachments/248063/FD9IWE4IXGFU5XD.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/><br />
<br />
<br />
<ul>
<li>Vermelho ==> 3.3V</li>
</ul>
<ul>
<li>Preto ==> GND</li>
</ul>
<ul>
<li>Amarelo ==> D4</li>
</ul>
Insira o NodeMCU, de forma que seus pinos correspondam ao diagrama elétrico acima. Observe que o chip pressionará o cabo do sensor, ajudando a manter os contatos do sensor no lugar.<br />
<br />
<img src="https://hackster.imgix.net/uploads/attachments/248064/FZGN79XIXGFU3RD.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/><br />
<br />
introduza um resistor de 4.7K ohms entre VCC (3.3V) e Data (D4)<br />
<br />
<img src="https://hackster.imgix.net/uploads/attachments/248065/FKR3YL3IXGFU3RX.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/><br />
<h3 id="toc-step-4--installing-the-appropriated-libraries-3">4: Instalando as bibliotecas apropriadas</h3>
Para o uso apropriado e de maneira simplificada do DS18B20, será necessária a instalação de 2 novas bibliotecas:<br />
<ul>
<li><a href="https://github.com/adafruit/ESP8266-Arduino/tree/esp8266/libraries/OneWire" target="_blank" rel="nofollow">OneWire</a></li>
</ul>
<ul>
<li><a href="https://github.com/milesburton/Arduino-Temperature-Control-Library" target="_blank" rel="nofollow">DallasTemperature</a></li>
</ul>
Instale ambas bibliotecas em seu diretório de Libraries do IDE<br />
<br />
Observe que a biblioteca OneWire DEVE ser a versão modificada para ser usada com o ESP8266, caso contrário você receberá um erro durante a compilação. Você encontrará a última versão no link acima ou fazendo o download do arquivo zip abaixo:<br />
<div class="embed-frame"><div class="figure document"><div class="embed original"><div class="document-widget"><div class="file"><a href="https://halckemy.s3.amazonaws.com/uploads/attachments/248058/F657JFLIXGFU7J4.zip" target="_blank">F657JFLIXGFU7J4.zip</a></div>
</div>
</div>
</div>
</div>
<p></p>
<p></p>
<h3 id="toc-step-5--testing-the-sensor-4">5: Testando o sensor</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider">Para testar o sensor, você poderá usar o código "<em>Simple.ino</em>" incluído nos <em><strong>Exemplos</strong></em> de Biblioteca, conforme mostrado na foto.</div>
</div>
</div>
</div>
</div>
<img src="https://hackster.imgix.net/uploads/attachments/248067/FGLEANLIXGFU9Q1.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/><br />
Carregue o código em seu NodeMCU e monitore a temperature utilizando-se do Serial Monitor IDE.<br />
<br />
<img src="https://hackster.imgix.net/uploads/attachments/248068/FP44Q1EIXKPXU98.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/><br />
<br />
<p></p>
<p></p>
<h3 id="toc-step-6--using-blynk-5">6: Utilizando o Blynk</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide">Quando formos capturar dados de temperatura, é importante ver-los desde qualquer lugar. Para isso, usaremos o Blynk. Desta maneira, todos os dados capturados serão exibidos em tempo real em seu dispositivo móvel podendo incluso serem armazenados em um arquivo histórico para análise posterior.</div>
<div class="image slick-slide"></div>
<p class="image slick-slide">Siga os passos abaixo para criar o App:</p>
<br />
<h5 class="image slick-slide">Criar um novo projeto.</h5>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<img src="https://hackster.imgix.net/uploads/attachments/248069/F8TYNNRIXKPXZMZ.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/><br />
<ul>
<li>Defina um nome (em meu caso: “Temperature Sensor”)</li>
</ul>
<ul>
<li>Selecione "NodeMCU" (ESP8266+WiFi) como <em>HW Model</em></li>
</ul>
<ul>
<li>Copie o AUTH TOKEN a ser utilizado em seu programa (voce poderá enviar-lo diretamente a seu email).</li>
</ul>
<h5>Inclua um “Gauge” Widget</h5>
<img src="https://hackster.imgix.net/uploads/attachments/248070/FJYOKCNIXKPXZEW.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/><br />
Defina:<br />
<ul>
<li>Virtual pin a ser utilizado com o sensor: <strong>V10</strong></li>
</ul>
<ul>
<li>A faixa de temperatura: <strong>-10 to 100 oC</strong></li>
</ul>
<ul>
<li>A frequência para leitura dos dados: <strong>1 sec</strong></li>
</ul>
<h5>Includes a “History Graph” Widget,</h5>
definir <strong>V10</strong> como <strong>virtual pin</strong><br />
<br />
<img src="https://hackster.imgix.net/uploads/attachments/248071/FVJ39FKIXKPXZIM.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/><br />
<h5>Press “Play” (The triangle at right up corner)</h5>
Naturalmente, o Blynk irá dizer-lhe que o NodeMCU está fora de linha. É hora de carregar o código completo no IDE do Arduino:<br />
<pre class="hljs dart"><code><span class="hljs-comment"><span class="markdown">/<span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span>** </span></span><span class="hljs-comment"><span class="markdown"> * IoT Temperature Monitor with Blynk
</span></span><span class="hljs-comment"><span class="markdown"> * Blynk library is licensed under MIT license<br />
</span></span><span class="hljs-comment"><span class="markdown"> * This example code is in public domain.<br />
</span></span><span class="hljs-comment"><span class="markdown"> * <br />
</span></span><span class="hljs-comment"><span class="markdown"> * Developed by Marcelo Rovai - 05 January 2017<br />
</span></span><span class="hljs-comment"><span class="markdown"> <span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-emphasis">***</span>/</span></span><br />
<span class="hljs-comment">/* ESP & Blynk */</span><br />
#include <br />
#include <br />
#define BLYNK_PRINT Serial <span class="hljs-comment">// Comment this out to disable prints and save space</span><br />
char auth[] = <span class="hljs-string">"YOUR AUTH CODE HERE"</span>;<br />
<br />
<span class="hljs-comment">/* WiFi credentials */</span><br />
char ssid[] = <span class="hljs-string">"YOUR SSID"</span>;<br />
char pass[] = <span class="hljs-string">"YOUR PASSWORD"</span>;<br />
<br />
<span class="hljs-comment">/* TIMER */</span><br />
#include <br />
SimpleTimer timer;<br />
<br />
<span class="hljs-comment">/* DS18B20 Temperature Sensor */</span><br />
#include <br />
#include <br />
#define ONE_WIRE_BUS <span class="hljs-number">2</span> <span class="hljs-comment">// DS18B20 on arduino pin2 corresponds to D4 on physical board</span><br />
OneWire oneWire(ONE_WIRE_BUS);<br />
DallasTemperature DS18B20(&oneWire);<br />
float temp;<br />
<br />
<span class="hljs-keyword">void</span> setup() <br />
{<br />
Serial.begin(<span class="hljs-number">115200</span>);<br />
Blynk.begin(auth, ssid, pass);<br />
DS18B20.begin();<br />
timer.setInterval(<span class="hljs-number">1000</span>L, getSendData);<br />
}<br />
<br />
<span class="hljs-keyword">void</span> loop() <br />
{<br />
timer.run(); <span class="hljs-comment">// Initiates SimpleTimer</span><br />
Blynk.run();<br />
}<br />
<br />
<span class="hljs-comment"><span class="markdown">/<span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span>*<br />
</span></span><span class="hljs-comment"><span class="markdown"> * Send Sensor data to Blynk<br />
</span></span><span class="hljs-comment"><span class="markdown"> <span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span><span class="hljs-strong">*****</span>/</span></span><br />
<span class="hljs-keyword">void</span> getSendData()<br />
{<br />
DS18B20.requestTemperatures(); <br />
temp = DS18B20.getTempCByIndex(<span class="hljs-number">0</span>);<br />
Serial.println(temp);<br />
Blynk.virtualWrite(<span class="hljs-number">10</span>, temp); <span class="hljs-comment">//virtual pin V10</span><br />
}<br />
</code></pre>
Assim que o código for carregado e estiver em execução, verifique a aplicação BLYNK. Esta deverá também estar em execução.<br />
<br />
Abaixo do código completo do Arduino para o seu projeto:<br />
<br />
<a href="https://halckemy.s3.amazonaws.com/uploads/attachments/248059/F05G780IXKPYLO4.ino" target="_blank">F05G780IXKPYLO4.ino</a><br />
<p></p>
<p></p>
<h3 id="toc-step-7--conclusion-6">7: Conclusão</h3>
<div class="embed-frame"></div>
Como sempre, espero que este projecto possa ajudar outras pessoas a encontrarem o seu caminho no emocionante mundo da electrónica e do IoT!<br />
<br />
"Saludos desde el sur del mundo!"<br />
<br />
Vejo você em meu próximo post!<br />
<br />
Obrigado<br />
<br />
MarceloBrincando com eletrônica: Como utilizar a biblioteca “GPIO Zero” no Raspberry Pitag:labdegaragem.com,2016-12-23:6223006:BlogPost:5867882016-12-23T21:46:27.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p><a href="https://mjrobot.files.wordpress.com/2016/12/img_0129.jpg?w=768&h=1&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2016/12/img_0129.jpg?w=768&h=1&crop=1"></img></a> <br></br> Uma maneira simples de aprender eletrônica é usando o Raspberry Pi e sua biblioteca “GPIO Zero”. Com poucas linhas de código em Python, você poderá facilmente controlar atuadores, ler sensores, etc.</p>
<p>Aqui, neste rápido tutorial procurarei fornecer-lhes a base para a criação de circuitos simples, controlados pelo Raspberry Pi.</p>
<p>Pessoal,<br></br> Tentei…</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/12/img_0129.jpg?w=768&h=1&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/12/img_0129.jpg?w=768&h=1&crop=1" class="align-full"/></a><br/> Uma maneira simples de aprender eletrônica é usando o Raspberry Pi e sua biblioteca “GPIO Zero”. Com poucas linhas de código em Python, você poderá facilmente controlar atuadores, ler sensores, etc.</p>
<p>Aqui, neste rápido tutorial procurarei fornecer-lhes a base para a criação de circuitos simples, controlados pelo Raspberry Pi.</p>
<p>Pessoal,<br/> Tentei colocar todo o conteúdo aqui mas deu erro.<br/>
Segue o link para minha pagina:<br/>
<a href="https://mjrobot.org/2016/12/23/gpio-zero-raspberry-pi/?iframe=true&theme_preview=true" target="_blank">Brincando com eletrônica: Como utilizar a biblioteca “GPIO Zero” no Raspberry Pi</a></p>IoT: Sensor de movimento com o NodeMCU e BLYNKtag:labdegaragem.com,2016-12-03:6223006:BlogPost:5831142016-12-03T16:34:49.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p></p>
<div class="entry-content"><div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide"><a href="https://mjrobot.files.wordpress.com/2016/12/f9uolvuivo85ank-large.jpg?w=680&h=1&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2016/12/f9uolvuivo85ank-large.jpg?w=680&h=1&crop=1&width=700" width="700"></img></a> Simples tutorial para demonstrar a facilidade de…</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p></p>
<div class="entry-content"><div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide"><a href="https://mjrobot.files.wordpress.com/2016/12/f9uolvuivo85ank-large.jpg?w=680&h=1&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/12/f9uolvuivo85ank-large.jpg?w=680&h=1&crop=1&width=700" width="700" class="align-full"/></a>
Simples tutorial para demonstrar a facilidade de implementação de um projeto do tipo “Internet das Coisas” (IoT) com o NodeMCU e o Blynk.<br />
<p></p>
<p>Toda vez que um movimento é detectado pelo sensor, uma mensagem fornecida pelo aplicativo Blynk é enviada para um smartphone.</p>
<br />
<a class="embed-img"><img src="https://hackster.imgix.net/uploads/attachments/233254/FS275NPIVO85AX7.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></a><br />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p> </p>
<h3>.</h3>
<h3 id="toc-step-1--bill-of-material-0">Step 1: Principais componentes</h3>
<ul>
<li><a href="https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/ref=sr_1_fkmr1_1?ie=UTF8&qid=1480534713&sr=8-1-fkmr1&keywords=NodeMCU+ESP12-E">NodeMCU ESP12-E</a> $8.89</li>
</ul>
<ul>
<li><a href="https://www.amazon.com/Motion-HC-SR501-Infrared-Arduino-Raspberry/dp/B00M1H7KBW/ref=sr_1_4_a_it?ie=UTF8&qid=1480534787&sr=8-4&keywords=Motion+Sensor+HC-SR501">Motion Sensor HC-SR501</a> $2.57</li>
</ul>
<ul>
<li>Resistor (1K, 2.2K and 330ohm)</li>
</ul>
<ul>
<li>LED</li>
</ul>
<ul>
<li>Breadboard</li>
</ul>
<ul>
<li>Cables</li>
</ul>
<h3>.</h3>
<h3 id="toc-step-2--the-hc-sr501-passive-infrared--pir--motion-sensor-1">Step 2: O HC-SR501 “Passive Infrared (PIR) Motion Sensor”</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="figcaption embed-figcaption"></div>
<div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"><a class="embed-img"><img src="https://hackster.imgix.net/uploads/attachments/233255/FJKY8QBIVO85DNM.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/> </a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p>Este módulo de sensor de movimento utiliza-se do sensor passivo de sinal infravermelho <em><span>LHI778 </span></em>e o do circuito integrado<em><span> </span><span>BISS0001</span> </em>para controlar como o “movimento deve ser detectado”.</p>
<p><img src="https://hackster.imgix.net/uploads/attachments/233257/FJHDQ6GIVO85EXB.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<p>O módulo possui sensibilidade ajustável que permite uma faixa de detecção de movimento de 3 a 7 metros.</p>
<p><img src="https://hackster.imgix.net/uploads/attachments/233256/FAXRXAJIVO85EY2.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<p>O módulo também inclui ajustes de atraso de tempo e seleção de gatilho que permitem ajustes finos dentro de sua aplicação.</p>
<p><img class="size-full wp-image-7971 alignleft" src="https://mjrobot.files.wordpress.com/2016/12/fkscpzbivo85exc-large.jpg?w=840" alt="fkscpzbivo85exc-large"/>https://mjrobot.files.wordpress.com/2016/12/fkscpzbivo85exc-large.jpg?w=150 150w" sizes="(max-width: 300px) 85vw, 300px" /></p>
<p><img class="size-full wp-image-7972 aligncenter" src="https://mjrobot.files.wordpress.com/2016/12/f19wasdivo85ey1-large.jpg?w=840" alt="f19wasdivo85ey1-large"/>https://mjrobot.files.wordpress.com/2016/12/f19wasdivo85ey1-large.jpg?w=150 150w" sizes="(max-width: 300px) 85vw, 300px" /></p>
<p> </p>
<p>O link abaixo nos fornece mais detalhes do funcionamanto do sensor:</p>
<p><a href="http://henrysbench.capnfatz.com/henrys-bench/arduino-sensors-and-input/arduino-hc-sr501-motion-sensor-tutorial/">Arduino HC-SR501 Motion Sensor Tutorial</a></p>
<h3>.</h3>
<h3 id="toc-step-3--the-hw-2">Step 3: O HW</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"><a class="embed-img"><img src="https://hackster.imgix.net/uploads/attachments/233260/F0SZ7BYIVO85IK3.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p>O HW é muito simples. O sensor tem 3 pinos (+ 5V, GND e Saída).</p>
<blockquote><p><span>É importante lembrar que a saída do HC-SR501 gera um sinal lógico de + 5V (ALTO) ou 0V (LOW), o qual NÃO É COMPATÍVEL com os níveis de entrada do NodeMCU, que funciona com o nível 3.3V.</span></p>
</blockquote>
<p>Assim, você precisará de um divisor de tensão para converter os níveis de sinal (veja o diagrama elétrico acima).</p>
<ul>
<li>Saída do HC-SR501 ==> para a entrada do divisor de tensão</li>
<li>NodeMCU Pin D1 (GPIO 5) ==> para o ponto médio do Divisor de Tensão</li>
</ul>
<p>Também incluíremos um LED no pino D7 (GPIO13), para uma visualização local.</p>
<h3>.</h3>
<h3 id="toc-step-4--testing-the-sensor-3">Step 4: Testando o sensor</h3>
<p>Primeiramente faremos um programinha simples para testar e calibrar o sensor.</p>
<p>Carregue o código abaixo no Arduino IDE:</p>
<p></p>
<p><span style="color: #993300;">/* HC-SR501 Motion Detector */</span><br/> <span style="color: #993300;">#define ledPin D7 // Red LED</span><br/> <span style="color: #993300;">#define pirPin D1 // Input for HC-SR501</span><br/> <span style="color: #993300;">int pirValue; // variable to store read PIR Value</span><br/> <span style="color: #993300;">void setup()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> pinMode(ledPin, OUTPUT);</span><br/> <span style="color: #993300;"> pinMode(pirPin, INPUT);</span><br/> <span style="color: #993300;"> digitalWrite(ledPin, LOW);</span><br/> <span style="color: #993300;">}</span><br/> <span style="color: #993300;">void loop()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> pirValue = digitalRead(pirPin);</span><br/> <span style="color: #993300;"> digitalWrite(ledPin, pirValue);</span><br/> <span style="color: #993300;">}</span></p>
<pre class="hljs arduino"><code><span class="hljs-comment"><br/><br/>
</span></code></pre>
<p>Ao fazer um movimento na frente do sensor, você verá o LED vermelho acender. Você poderá usar o código acima para ajustes no sensor, se necessário.</p>
<p>Se você não sabe como preparar o IDE do arduino para trabalhar com o NodeMCU, por favor de uma olhadinha em meu tutorial:</p>
<p><a href="https://mjrobot.org/2016/10/15/do-blink-ao-blynk/" target="_blank">Do “blink” ao BLYNK, uma viagem pela “Internet das coisas” nas asas do NodeMCU ESP-12E</a></p>
<p>.</p>
<h3 id="toc-step-5--including-blynk-4">Step 5: Incluindo o BLYNK</h3>
<div class="embed-frame"></div>
<p>Siga os Passos abaixo::</p>
<ul>
<li>Crie um <span>New Project</span>.</li>
</ul>
<ul>
<li>Defina um nome para o projeto (em meu caso: “<span>Motion Detector</span>“)</li>
</ul>
<p><img src="https://hackster.imgix.net/uploads/attachments/233261/F91PRYBIVO85K8B.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<ul>
<li>Selecione <span>NodeMCU</span> como HW Model</li>
</ul>
<ul>
<li>Copie o <span>AUTH TOKEN</span> para ser adicionado ao seu código do IDE (o melhor é enviar-lo para seu email).</li>
</ul>
<ul>
<li>Inclua o “Widget”: <span>Push Notification</span>.</li>
</ul>
<p><img src="https://hackster.imgix.net/uploads/attachments/233262/FUKXGF9IVO85K6H.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<ul>
<li>Pressione “<span>Play</span>” (o triangulo no canto superior direito)</li>
</ul>
<p><a href="https://mjrobot.files.wordpress.com/2016/12/fyieb1nivo85k5p-large.jpg?w=295&h=524" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/12/fyieb1nivo85k5p-large.jpg?w=295&h=524" class="align-full"/></a></p>
<p>Naturalmante o appicativo Blynk nesse ponto irá informar que o NodeMCU está off-line. Antes de rodar o aplicativo Blynk, o codigo deve ser carregado e iniciado no módulo NodeMCU.</p>
<p>Abaixo o código completo para ser executado no Arduino IDE (não se esqueça de entrar com seus dados):</p>
<div class="embed-frame"><div class="figure document"><div class="figcaption embed-figcaption"></div>
<div class="embed original"><div class="document-widget"><div class="file"><a href="https://halckemy.s3.amazonaws.com/uploads/attachments/233252/FMYQOHTIVO85PDY.ino">FMYQOHTIVO85PDY.ino</a></div>
<p></p>
<p>Assim que o código é carregado e executado, verifique a aplicação BLYNK, a qual também deverá estar funcionando.<br/> Faça um movimento na frente do sensor, você deverá receber uma mensagem em seu celular como a mostrada abaixo:</p>
</div>
</div>
</div>
</div>
<pre class="hljs dart"></pre>
<p></p>
<p><img src="https://hackster.imgix.net/uploads/attachments/233264/FPPIX2DIVO85K5K.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<p></p>
<h3>.</h3>
<h3 id="toc-step-6--conclusion-5">Step 6: Conclusão</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="figcaption embed-figcaption"><p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979600438?profile=original" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979600438?profile=RESIZE_480x480" width="400" class="align-full"/></a></p>
<p>Como sempre, espero que este projeto ajude outras pessoas a encontrar seu caminho no apaixonante mundo da eletrônica e do IoT!</p>
<p>Um abraço e até o próximo post!</p>
<p><span class="s1">"Saludos desde el sur del mundo!" ;-)</span></p>
<p>Obrigado</p>
<p>Marcelo</p>
</div>
</div>
</div>
</div>LaserCat – IoT com NodeMCU e Blynktag:labdegaragem.com,2016-12-03:6223006:BlogPost:5831122016-12-03T16:16:17.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="entry-summary"><p>Exploraremos como controlar servos via internet, utilizando-se o NodeMCU ESP12-E e o Blynk.</p>
</div>
<p><a href="https://mjrobot.files.wordpress.com/2016/11/frtj0aviv0b7svf-large.jpg?w=680&h=1&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2016/11/frtj0aviv0b7svf-large.jpg?w=680&h=1&crop=1&width=700" width="700"></img></a></p>
<div class="entry-content"><div class="embed-frame"><div class="figure image_widget"><div class="figcaption embed-figcaption">Este é um projeto muito simples, onde a idéia principal é explorar como controlar servos via…</div>
</div>
</div>
</div>
<div class="entry-summary"><p>Exploraremos como controlar servos via internet, utilizando-se o NodeMCU ESP12-E e o Blynk.</p>
</div>
<p><a href="https://mjrobot.files.wordpress.com/2016/11/frtj0aviv0b7svf-large.jpg?w=680&h=1&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/11/frtj0aviv0b7svf-large.jpg?w=680&h=1&crop=1&width=700" width="700" class="align-full"/></a></p>
<div class="entry-content"><div class="embed-frame"><div class="figure image_widget"><div class="figcaption embed-figcaption">Este é um projeto muito simples, onde a idéia principal é explorar como controlar servos via internet. Para isso, usaremos uma grande dupla de componentes, o <em><span>NodeMCU ESP12-E</span></em> e um aplicativo <em><span>Blynk</span></em>.</div>
<div class="figcaption embed-figcaption"></div>
<div class="figcaption embed-figcaption">O projeto foi baseado em um grande tutorial: <a href="http://www.instructables.com/id/Smartphone-Controlled-Cat-Laser/" target="_blank">Smartphone Controlled Cat Laser</a>, desenvolvido usando-se um Arduino Uno conectado a um PC via Serial. Aqui porém, usaremos o NodeMCU, em um formato mais “portátil” utilizando-se WiFi e bateria.</div>
</div>
</div>
<p><img src="https://hackster.imgix.net/uploads/attachments/222019/FI8HX70IV0B7SA0.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<blockquote><p><span>IMPORTANTE</span>: O apontador laser pode ser perigoso se apontado diretamente para os olhos. Proteja os seus olhos, o de animais e outras pessoas. <span>Use com cuidado</span>.</p>
</blockquote>
<p></p>
<p>Abaixo, você poderá ver minha gatinha Cleo brincando com o laser:</p>
<div class="embed-frame"><div class="figure youtube"><div class="figcaption embed-figcaption"></div>
<div class="embed widescreen"><div class="jetpack-video-wrapper"><div class="jetpack-video-wrapper"><a href="https://youtu.be/GPm8n1r1P7g">https://youtu.be/GPm8n1r1P7g</a></div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper">.</div>
</div>
</div>
</div>
</div>
<h3 id="toc-step-1--bill-of-material-0">Step 1: Os componentes principais:</h3>
<ul>
<li><a href="https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/ref=pd_sim_147_2?_encoding=UTF8&psc=1&refRID=X13PC1FK1SHEM2EA763Q">NodeMCU ESP12-E</a></li>
</ul>
<ul>
<li><a href="https://www.amazon.com/TowerPro-SG90-Micro-Servo-2pk/dp/B01608II3Q/ref=pd_sim_sbs_147_7?_encoding=UTF8&psc=1&refRID=970EFR3NCXTZ9CQCGDRY">Micro Servos (2x)</a></li>
</ul>
<ul>
<li><a href="https://www.amazon.com/New-grams-KY-008-Transmitter-Arduino/dp/B01MPZK5VT/ref=sr_1_4?ie=UTF8&qid=1478528554&sr=8-4&keywords=laser+pointer+arduino">Laser Pointer</a></li>
</ul>
<p></p>
<h3 id="toc-step-2--pan-tilt-mechanism-1">Step 2: O mecanismo “Pan/Tilt” de posicionamento</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"><a class="embed-img"><img src="https://hackster.imgix.net/uploads/attachments/222021/FN4PJTNIV0B6VPN.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max" width="558" height="710"/></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p></p>
<p>Vamos construir um mecanismo de “Pan / Tilt” muito simples, montando os servos “um em cima do outro” como mostrado nas fotos abaixo:</p>
<ul>
<li>O “Pan” Servo é usado “como base”. Mantenha-o na vertical.</li>
</ul>
<p><img src="https://hackster.imgix.net/uploads/attachments/222022/F26QDUYIV0B6TMW.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max" width="601" height="561"/></p>
<p></p>
<ul>
<li>Fixe o “Tilt” Servo sobre a parte de movimento do “Pan” Servo (na posição horizontal)</li>
</ul>
<ul>
<li>Fixe o ponteiro laser na parte movel do “Tilt” Servo como mostrado.</li>
</ul>
<p><img src="https://hackster.imgix.net/uploads/attachments/222023/FOFEZ6MIV0B6TOP.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max" width="541" height="564"/></p>
<p></p>
<p>Note que usei algumas peças metálicas, aproveitadas de um brinquedo desmontado, como estrutura de base para o mecanismo “Pan / Tilt”. Você poderá utilizar outros tipos de estrutura, O importante é manter os movimentos horizontal e vertical.</p>
<h3 id="toc-step-3--the-hw-2">Step 3: O HW</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"></div>
<div class="image slick-slide"></div>
<div class="image slick-slide"><a class="embed-img"><img src="https://hackster.imgix.net/uploads/attachments/222027/FIBBXV0IV0A9A43.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max" width="595" height="794"/></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p></p>
<p>O circuito elétrico é bem simples:</p>
<p><img src="https://hackster.imgix.net/uploads/attachments/222025/FV8XREFIV0B6XWB.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<p></p>
<p>Antes de iniciar as conexões, leve em consideração que <span><span>apesar do nodeMCU ser alimentado com 5V, ele funciona internamente com 3.3V (assim como seus pinos de I/O)</span></span>. Assim, os Servos não poderão ser alimentados a partir de uma das 3 saídas de 3.3V do NodeMCU. A exceção é o pino “Vin”, que pode tanto fornecer 5V para o breadboard “+ VCC rail”quanto alimentar o NodeMCU quando uma fonte externa é utilizada (como mostrado no diagrama elétrico abaixo).</p>
<p></p>
<p><img src="https://hackster.imgix.net/uploads/attachments/222039/ZiAIEC5ggwo2RgPvjleA.png?auto=compress%2Cformat&w=680&h=510&fit=max"/></p>
<p></p>
<p>O módulo laser deve ser alimentado com 5V, porém ele também funciona com 3.3V o que faz com que a potência do laser seja menor e consequentemente, seu uso mais seguro.</p>
<blockquote><p><span>IMPORTANTE</span>: O apontador laser pode ser perigoso se apontado diretamente para os olhos. Proteja os seus olhos, o de animais e outras pessoas. <span>Use com cuidado</span>.</p>
</blockquote>
<p></p>
<p>Observando atentamente o diagrama elétrico acima, execute as seguientes ligações:</p>
<ul>
<li>Ligue o cabo de dados do servo Pan (eixo X) ao NodeMCU Pin D1 (note que todos os pinos digitais do NodeMCU são PWM)</li>
<li>Ligue os dados do servo Tilt (eixo “Y”) ao NodeMCU Pin D2</li>
<li>Ligue o pino “S” do ponteiro laser ao NodeMCU Pin D3</li>
<li>Ligue o pino “Vin” de NodeMCU ao “+ 5V Rail” do Breadboard</li>
<li>Conecte os pinos GND (comum ou terra) do NodeMCU, Servos e Ponteiro Laser ao “GND Rail” do Breadboard</li>
<li>Conecte oscabos de alimantação dos Servos ao “+ 5V Rail” do Breadboard</li>
</ul>
<p> </p>
<h3 id="toc-step-4--the-code-3">Step 4: O codigo</h3>
<p>Para o controle dos servos, usaremos a biblioteca do IDE: <em><span>Servo.h,</span></em> a qual gerará sinais PWM posicionando-os facilmente com entradas angulares.</p>
<p>Uma vez que a base do projeto é usar o aplicativo <em><span>BLYNK</span></em>, o código torna-se muito simples. Devemos definir 4 variáveis virtuais:</p>
<p><em><span>V0: “X position”</span></em></p>
<p><em><span>V1: “Y position”</span></em></p>
<p><em><span>V2: “Random or manual” operation</span></em></p>
<p><em><span>V3: Laser ON/OFF command</span></em></p>
<p></p>
<p><span style="color: #993300;">BLYNK_WRITE(V0) { xPotReading = param.asInt(); }</span> <br/> <span style="color: #993300;">BLYNK_WRITE(V1) { yPotReading = param.asInt(); }</span> <br/> <span style="color: #993300;">BLYNK_WRITE(V2) { randState = param.asInt(); }</span> <br/> <span style="color: #993300;">BLYNK_WRITE(V4) { laserState = param.asInt(); }</span></p>
<p></p>
<p><span>Se você não sabe como preparar o IDE do arduino para trabalhar com o NodeMCU, por favor de uma olhadinha em meu tutorial:</span></p>
<p><a href="https://mjrobot.org/2016/10/15/do-blink-ao-blynk/" target="_blank">Do “blink” ao BLYNK, uma viagem pela “Internet das coisas” nas asas do NodeMCU ESP-12E</a></p>
<pre class="hljs mipsasm"><a href="https://mjrobot.org/2016/10/15/do-blink-ao-blynk/" target="_blank"></a></pre>
<p></p>
<p>Abaixo, o código completo. de uma passada de olhos nele. É muito fácil de entender.</p>
<div class="embed-frame"><div class="figure document"><div class="embed original"><div class="document-widget"><div class="file"><a href="https://halckemy.s3.amazonaws.com/uploads/attachments/222018/FDVVSYNIV0B7TTE.ino">FDVVSYNIV0B7TTE.ino</a></div>
<div class="file"></div>
</div>
</div>
</div>
</div>
<h3>.</h3>
<h3 id="toc-step-5--blynk-4">Step 5: O “Blynk”</h3>
<div class="embed-frame"><div class="figure image_widget"><div class="embed original"><div class="image-gallery-container"><div class="image-gallery slick-initialized slick-slider"><div class="slick-list draggable"><div class="slick-track"><div class="image slick-slide slick-active"><a class="embed-img"><img src="https://hackster.imgix.net/uploads/attachments/222028/FY3EEJ1IV0B7HKZ.LARGE.jpg?auto=compress%2Cformat&w=680&h=510&fit=max" width="635" height="749"/></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<h3 id="toc-step-6--conclusion-5">Step 6: Conclusão</h3>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979600921?profile=original" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979600921?profile=RESIZE_480x480" width="400" class="align-full"/></a></p>
<p>Como sempre, espero que este projeto ajude outras pessoas a encontrar seu caminho no apaixonante mundo da eletrônica e do IoT!</p>
<p>Um abraço e até o próximo post!</p>
<p>Obrigado</p>
<p class="p2"><span class="s1">Saludos desde o sul do mundo!</span></p>
<p class="p2">Marcelo</p>
</div>Do “blink” ao BLYNK, uma viagem pela “Internet das coisas” nas asas do NodeMCU ESP-12Etag:labdegaragem.com,2016-11-03:6223006:BlogPost:5757402016-11-03T10:43:27.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="step-container"><div class="step-body"><p><a href="https://mjrobot.files.wordpress.com/2016/10/mainphoto2.png?w=1024&h=1&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2016/10/mainphoto2.png?w=1024&h=1&crop=1&width=700" width="700"></img></a></p>
<p></p>
<p>Neste tutorial, aprenderemos a lidar com este fantástico dispositivo, o <em>NodeMCU ESP-12E Development Kit V. 1.0, </em>onde aprenderemos como:</p>
<ul>
<li>Fazer piscar um LED pela internet</li>
<li>Ligar o ESP a um display LCD do tipo “OLED”</li>
<li>Capturar dados gerados por sensores tanto…</li>
</ul>
</div>
</div>
<div class="step-container"><div class="step-body"><p><a href="https://mjrobot.files.wordpress.com/2016/10/mainphoto2.png?w=1024&h=1&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/10/mainphoto2.png?w=1024&h=1&crop=1&width=700" width="700" class="align-full"/></a></p>
<p></p>
<p>Neste tutorial, aprenderemos a lidar com este fantástico dispositivo, o <em>NodeMCU ESP-12E Development Kit V. 1.0, </em>onde aprenderemos como:</p>
<ul>
<li>Fazer piscar um LED pela internet</li>
<li>Ligar o ESP a um display LCD do tipo “OLED”</li>
<li>Capturar dados gerados por sensores tanto analógicos como digitais</li>
<li>Subir dados a um serviço de Internet das coisas tal como o <em>Thinkspeak</em></li>
<li>Controlar “coisas” pela internet, utilisando-se aplicativos para smartphones como o <em>BLINK</em></li>
</ul>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step1" class="step-title">1: Lista de Material</h2>
<div class="step-body"><ol>
<li><a href="https://www.amazon.com/gp/product/B010O1G1ES/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1" target="_blank">Node MCU ESP-12E Development Kit V 1.0</a></li>
<li><a href="https://www.amazon.com/LANMU-Serial-128X64-Display-Arduino/dp/B01G6SAWNY/ref=pd_sim_147_2?ie=UTF8&pd_rd_i=B01G6SAWNY&pd_rd_r=67HC4XFB5W6DWX1H6DWE&pd_rd_w=vFEwd&pd_rd_wg=1RwJc&psc=1&refRID=67HC4XFB5W6DWX1H6DWE" target="_blank">0.96″ I2C IIC SPI Serial 128X64 Yellow&Blue OLED LCD LED Display</a></li>
<li><a href="https://www.amazon.com/Gikfun-Temperature-Humidity-Arduino-EK1196_/dp/B00Z5Y5UEM/ref=sr_1_5?s=pc&ie=UTF8&qid=1476221974&sr=1-5&keywords=dht22" target="_blank">DHT22 AM2302 Temperature And Humidity Sensor</a></li>
<li><a href="https://www.amazon.com/Comparator-Hygrometer-moisture-Raspberry-RBTMKR/dp/B015T8BBX2/ref=sr_1_cc_1?s=aps&ie=UTF8&qid=1476222131&sr=1-1-catcorr&keywords=yl69" target="_blank">YL-69 sensor and LM393 Comparator module soil medium Hygrometer,</a></li>
<li>Breadboard</li>
<li>LED</li>
<li>Resistor 10K ohms</li>
<li>Cabos</li>
</ol>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step2" class="step-title">2: O NodeMCU</h2>
<div id="photoset-SKJHC06IU5V061M" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><img class="lazy-img" src="https://cdn.instructables.com/FAP/8RBD/IU5N7Y2W/FAP8RBDIU5N7Y2W.MEDIUM.jpg" alt="nodeMCU.jpg"/></div>
</div>
</div>
</div>
<div class="step-body"><p>O NodeMCU ESP-12E é a versão integrada do popular ESP8266, um <em>Serial to Wi-Fi System On a Chip (SoC)</em>, 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, <em><a href="http://espressif.com/products/hardware/esp8266ex/overview/" target="_blank">Espressif Systems</a></em>, uma fabricante de circuitos integrados focada no desenvolvimento de chips de RF, particularmente Wi-Fi.</p>
<p>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: <a href="http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family" target="_blank">Família ESP8266 </a>.</p>
<p>Os 2 módulos mais importantes são sem dúvida, a ESP-01 e o ESP-12E.</p>
<p>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:</p>
<p><span><a href="https://mjrobot.org/2016/01/17/o-esp8266-serial-wifi-module/?iframe=true&theme_preview=true" target="_blank">O ESP8266 – Parte 1</a>, <a href="https://mjrobot.org/2016/01/19/o-esp8266-parte-2-web-server/?iframe=true&theme_preview=true" target="_blank">Parte 2</a>, <a href="https://mjrobot.org/2016/01/21/o-esp8266-parte-3-acionando-leds-remotamente/?iframe=true&theme_preview=true" target="_blank">Parte 3</a></span></p>
<p><span>O ESP-12E Development Board (NodeMCU DevKit 1.0)</span></p>
<p>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:</p>
<ul>
<li>Adaptador USB para UART: Silicon Labs CP2102,</li>
<li>NCP1117 3,3VDC Voltage Regulator,</li>
<li>Conector micro-USB,</li>
<li>Pinos adicionais com GND, Vin, 3,3VDC para facilitar o acesso durante o desenvolvimento.</li>
</ul>
<p>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 !</p>
<p><span>Especificações Técnicas:</span></p>
<ul>
<li>Support STA/AP/STA+AP 3 working modes;</li>
<li>Built-in TCP/IP protocol stack, support multiple-channel TCP Client connection (max 5);</li>
<li>0~D8, SD1~SD3: used for GPIO, PWM (D1-D8), IIC, ect; the driven ability can be arrived at 15mA;</li>
<li>AD0: one-way 10 bits ADC;</li>
<li>Power input: 4.5V~9V(10VMAX), support USB powered and USB debug;</li>
<li>Working current: ≈70mA(200mA MAX, continue), standby<200uA;</li>
<li>Transmission data rate: 110-460800bps;</li>
<li>Support UART/GPIO data communication interface;</li>
<li>Support update firmware remotely (OTA);</li>
<li>Support Smart Link;</li>
<li>Working temperature:-40℃~+125℃;</li>
<li>Driven mode: double large-power H bridge driven</li>
<li>Weight: 7g.</li>
</ul>
<p><img src="https://cdn.instructables.com/F8M/4YT9/IU5N7WNP/F8M4YT9IU5N7WNP.MEDIUM.jpg" alt="Picture of The NodeMCU"/></p>
<p>Um excelente site para se aprender mais sobre a família do ESP 8266 é: <a href="http://learn.acrobotic.com/tutorials/post/what-is-the-esp8266#" target="_blank">What Is The ESP8266 And Why Is It So Popular?</a></p>
<p> </p>
</div>
</div>
<div class="step-container"><h2 id="step3" class="step-title">3: Instalando o NodeMCU ao IDE do Arduino</h2>
<div id="photoset-SD91PY5IU5V06B4" class="photoset"></div>
<div class="step-body"><p>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.</p>
<p>Comecemos:</p>
<p>No Arduino IDE, abra a janela de preferências e digite a URL (marcado em vermelho na foto abaixo) no campo <em>Additional Boards Manager URLs</em> e selecione <em>OK</em>.</p>
<pre><em><span><span><span class="font-size-3" style="color: #993300;"><a href="http://arduino.esp8266.com/stable/package_esp8266com_index.json">http://arduino.esp8266.com/stable/package_esp8266com_index.json</a></span><br/><br/>
</span></span></em></pre>
<p><img src="https://cdn.instructables.com/F89/TTMU/IU5N830E/F89TTMUIU5N830E.MEDIUM.jpg" alt="Picture of Installing the NodeMCU board at Arduino IDE"/></p>
<ul>
<li>Selecione <span>MENU</span> <span>→</span><span> Tools → Board → Boards Manager</span>…e vá rolando até encontrar a opção: <em>esp8266 by ESP8266 Community</em> , a qual deverá ser o último item da lista e clique <span>INSTALL</span></li>
</ul>
<p><img class="alignnone size-full wp-image-7345 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png?w=840" alt="arduino_ide_boards_esp8266"/><a href="https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png?w=150">https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png?w=300">https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png?w=768">https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png?w=768</a> 768w, <a href="https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png">https://mjrobot.files.wordpress.com/2016/10/arduino_ide_boards_esp8266.png</a> 912w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></p>
<ul>
<li>Instalando USB Drivers: O <em>USB to Serial UART module</em> incluído no dispositivo, é o <em>Silicon Labs’ CP2102</em>, para o qual deveremos instalar o driver <em>Virtual COM Port (VCP)</em>. No caso de meu MAC, o arquivo criado para comunicar com o CP2102 foi: <span>/dev/cu.SLAB_USBtoUART.</span> Você pode encontrar o driver apropriado ao seu computador no seguinte link: <a href="https://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx" target="_blank">CP210x USB to UART Bridge VCP Drivers</a></li>
<li>Depois de restartar o Arduino IDE , poderemos selecionar a placa no menu: <span>Option Tools → Board → NodeMCU 1.0 (ESP-12E Module). </span>Em seguida, especificar a correta frequência de operação da CPU: (<span>Tools → CPU Frequency: “” → 80MHz)</span> e velocidade de comunicação (<span>Tools → Upload Speed: “” → 115,200</span>). Finalmente, selecionar o port apropriado ao seu computador: (<span>Tools → Port → /dev/cu.SLAB_USBtoUART</span>).</li>
</ul>
<p></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-3.png?w=768" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-3.png?w=768&width=700" width="700" class="align-full"/></a></p>
<p>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:<span> File → Examples → ESP8266WiFi → WiFiScan</span>. Após o <em>upload</em>, podemos abrir a janela do <em>Serial Monitor</em> e observar os resultados. Verifique que 115,200 baud é a velocidade selecionada no menu do canto inferior direito do <em>Serial Monitor.</em></p>
</div>
</div>
<div class="step-container"><h2 id="step4" class="step-title"><img class="alignnone size-full wp-image-7351 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=840" alt="nodemcu-ide-setup-4"/><a href="https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=1678">https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=1678</a> 1678w, <a href="https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=150">https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=300">https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=768">https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=768</a> 768w, <a href="https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=1024">https://mjrobot.files.wordpress.com/2016/10/nodemcu-ide-setup-4.png?w=1024</a> 1024w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></h2>
<h2 class="step-title"></h2>
<h2 class="step-title">4: Piscando (“Blinking”) o LED</h2>
<div id="photoset-SNIZAJRIU5N7Z08" class="photoset"><div class="photoset-row cols-2"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="http://www.instructables.com/file/FF21FIPIU5NB25C/" target="_blank"><img class="lazy-img" src="https://cdn.instructables.com/FF2/1FIP/IU5NB25C/FF21FIPIU5NB25C.MEDIUM.jpg" alt="FullSizeRender 24.jpg"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p> </p>
<p>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.</p>
<p><img src="https://cdn.instructables.com/FYT/SAB8/IU5NAWIM/FYTSAB8IU5NAWIM.MEDIUM.jpg" alt="Picture of Blinking a LED"/></p>
<p>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.</p>
<p><img class="lazy-img" src="https://cdn.instructables.com/FBE/3B3R/IU5NB3LI/FBE3B3RIU5NB3LI.MEDIUM.jpg" alt="blink.png"/></p>
<p>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:</p>
<p><span style="color: #993300;">/**********************************************</span><br/> <span style="color: #993300;">Blink</span><br/> <span style="color: #993300;">Connected to pin D7 (GPIO13) ESP8266 NODEMCU</span><br/> <span style="color: #993300;">**********************************************/</span></p>
<p><span style="color: #993300;">#define ledPin 13</span><br/> <span style="color: #993300;">// #define ledPin D7</span></p>
<p><span style="color: #993300;">void setup()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> pinMode(ledPin, OUTPUT);</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p><span style="color: #993300;">void loop()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> digitalWrite(ledPin, HIGH);</span> <br/> <span style="color: #993300;"> delay(1000);</span> <br/> <span style="color: #993300;"> digitalWrite(ledPin, LOW);</span> <br/> <span style="color: #993300;"> delay(1000);</span> <br/> <span style="color: #993300;">}</span></p>
<p>Há uma relação entre alguns dos pinos do NodeMCU e do Arduino, automaticamente identificados pelo IDE, tal como descrito abaixo:</p>
<ul>
<li><span>ESP ==> Arduino</span></li>
<li>D0 ==> 16</li>
<li>D1 ==> 5</li>
<li>D2 ==> 4</li>
<li>D3 ==> 0</li>
<li>D4 ==> 2</li>
<li>D5 ==> 14</li>
<li>D6 ==> 12</li>
<li>D7 ==> 13</li>
<li>D8 ==> 15</li>
<li>D9 ==> 3</li>
<li>D10 ==> 1</li>
</ul>
<p>Abaixo o código pronto para ser executado no IDE do Arduino:</p>
</div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/F4B/02X8/IU5NB8S0/F4B02X8IU5NB8S0.ino" target="_blank"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="NodeMCU_Blink.ino"/><span class="title">NodeMCU_Blink.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step5" class="step-title">5: Instalando o display de 0.96″ (OLED)</h2>
<div id="photoset-SHI493FIU5NB3XL" class="photoset"><div class="photoset-row cols-1"></div>
<div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="http://www.instructables.com/file/FKAWFEBIU5NB8HO/" target="_blank"><img class="lazy-img" src="https://cdn.instructables.com/FKA/WFEB/IU5NB8HO/FKAWFEBIU5NB8HO.MEDIUM.jpg" alt="FullSizeRender 25.jpg"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>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:</p>
<ul>
<li>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).</li>
<li>Comunicação via I2C : se deve conectar ao NodeMCU I2C pins, usando:<ul>
<li>SCL ==> D1 (equ. Arduino 5)</li>
<li>SDA ==> D2 (equ. Arduino 4)</li>
</ul>
</li>
</ul>
<p>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:</p>
<p><img src="https://cdn.instructables.com/FPQ/HN3K/IU5NB6DK/FPQHN3KIU5NB6DK.MEDIUM.jpg" alt="Picture of Using the 0.96" OLED display"/></p>
<p>Uma vez conectado o display, baixar e instalar a sua biblioteca em nosso Arduino IDE. Nós usaremos a versão ACROBOT abaixo:</p>
<p><a href="https://github.com/acrobotic/Ai_Ardulib_SSD1306" target="_blank">SSD1306 Arduino Library</a></p>
<p>Depois de ter reiniciado o IDE, a biblioteca deverá estar instalada. Carreguemos o sketch abaixo para testar o display OLED:</p>
<p><span style="color: #993300;">/***********************************************************************</span><br/> <span style="color: #993300;">* NodeMCU and OLED display "Hello World"</span><br/> <span style="color: #993300;">* Based on original code developed by: Makerbro at <a href="https://acrobotic.com">https://acrobotic.com</a></span><br/> <span style="color: #993300;">* MJRoBot 12Oct16</span><br/> <span style="color: #993300;">************************************************************************/</span></p>
<p><span style="color: #993300;">#include <Wire.h></span><br/> <span style="color: #993300;">#include <ACROBOTIC_SSD1306.h></span></p>
<p><span style="color: #993300;">void setup()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> Wire.begin();</span> <br/> <span style="color: #993300;"> oled.init(); // Initialze SSD1306 OLED display</span><br/> <span style="color: #993300;"> oled.clearDisplay(); // Clear screen</span><br/> <span style="color: #993300;"> oled.setTextXY(0,0); // Set cursor position, start of line 0</span><br/> <span style="color: #993300;"> oled.putString(" MJRoBot.org");</span><br/> <span style="color: #993300;"> oled.setTextXY(4,0); // Set cursor position, start of line 4</span><br/> <span style="color: #993300;"> oled.putString(" HELLO, WORLD");</span><br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p>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);</p>
<p>Abaixo o código para o “Hello World”:</p>
</div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FOK/K5M6/IU5NB8TT/FOKK5M6IU5NB8TT.ino" target="_blank"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="OLED_test.ino"/><span class="title">OLED_test.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step6" class="step-title">6: O NodeMCU e o DHT22 como uma estação climática</h2>
<div id="photoset-SCXZD5VIU5NB94O" class="photoset"><div class="photoset-row cols-2"><div class="photoset-cell image-cell"></div>
<div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="http://www.instructables.com/file/FEB6BB5IU5NBGZI/" target="_blank"><img class="lazy-img" src="https://cdn.instructables.com/FEB/6BB5/IU5NBGZI/FEB6BB5IU5NBGZI.MEDIUM.jpg" alt="57fe5c32937ddb5b790007f3.jpeg"/><img class=" alignleft" src="https://cdn.instructables.com/F6F/I4V7/IT1HZRF8/F6FI4V7IT1HZRF8.MEDIUM.gif" alt="Picture of NodeMCU as a local weather station using DHT22" width="236" height="281"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p> </p>
<p>Um dos sensores mais utilizados normalmente para se captar dados meteorológicos é o DHT22 (ou seu irmão, o DHT11), <span class="s1">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. </span></p>
<p class="p1"><span class="s1">De acordo com a sua <span class="s2"><a href="https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf" target="_blank">folha de dados</a> (Datasheet)</span>, 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).</span></p>
<p class="p1"><span class="s1">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: <a href="https://learn.adafruit.com/dht" target="_blank"><span class="s2">Tutorial DHT22 / 11</span></a>.</span></p>
<p class="p1"><span class="s1">O DHT22 tem 4 pinos (de frente para o sensor, o pino 1 é o mais esquerda):</span></p>
<ol class="ol1">
<li class="li1"><span class="s1">VCC (3 a 5V)</span></li>
<li class="li1"><span class="s1">saída de dados</span></li>
<li class="li1"><span class="s1">Não conectado</span></li>
<li class="li1"><span class="s1">GND (Terra)</span></li>
</ol>
<p><img class="lazy-img" src="https://cdn.instructables.com/FEZ/KWJD/IU5NBC3A/FEZKWJDIU5NBC3A.MEDIUM.jpg" alt="OLED_DHT22.png"/></p>
<p class="p1"><span class="s1">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).</span></p>
<p class="p1"><span class="s1">Uma vez que o sensor esteja instalado fisicamente no NodeMCU, baixe a biblioteca DHT a partir do repositório de programas: <a href="https://github.com/adafruit/DHT-sensor-library" target="_blank"><span class="s2">Adafruit github</span></a> e a instale junto as outras bibliotecas de seu IDE (ambiente de desenvolvimento de programas do Arduino).</span></p>
<p>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:</p>
</div>
<div id="rich-embed-files" class="ible-files"></div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FBQ/2P48/IU5NBGGQ/FBQ2P48IU5NBGGQ.ino" target="_blank"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="NodeMCU_DHT22_IoT_Local_Station_OLED.ino"/><span class="title">NodeMCU_DHT22_IoT_Local_Station_OLED.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step7" class="step-title">7: Instalando sensores analógicos</h2>
<div id="photoset-SLV06L0IU5NBHM4" class="photoset"><div class="photoset-row cols-1"></div>
<div class="photoset-row cols-2"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="http://www.instructables.com/file/FJJAKG5IU5NC63Y/" target="_blank"><img class="lazy-img" src="https://cdn.instructables.com/FJJ/AKG5/IU5NC63Y/FJJAKG5IU5NC63Y.MEDIUM.jpg" alt="57fe81bf50e1b6b8d60002fc.jpeg"/></a></div>
</div>
<div class="photoset-cell image-cell"></div>
</div>
</div>
<div class="step-body"><p>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.</p>
<p>Por exemplo, suponha que você necessite ler 2 sensores analógicos:</p>
<ul>
<li>LDR: para se medir a intencidade da luz</li>
<li>Higrômetro (Soil Moisture) para se medir a umidade do solo</li>
</ul>
<p>O que devemos fazer é “alimentar” individualmente cada um desses sensores 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. Para saber mais sobre múltiplas entradas analógicas, consulte o site:</p>
<p><a href="http://www.instructables.com/id/Multiple-Analog-Inputs-on-Only-One-Analoge-Pin/" target="_blank">Multiple analog inputs using one analoge pin</a></p>
<p><span>Higrômetro:</span></p>
<p><img class=" alignleft" src="https://cdn.instructables.com/FGB/7MAH/IU5NBXHH/FGB7MAHIU5NBXHH.MEDIUM.jpg" alt="Picture of Using Analog sensors " width="278" height="284"/>No <a href="https://mjrobot.org/2016/09/02/ardufarmbot-controlando-um-tomateiro-com-a-ajuda-de-um-arduino-e-internet-das-coisas-iot/?iframe=true&theme_preview=true" target="_blank">Projeto ArduFarmBot</a>, exploramos como trabalhar com um higrômetro para medir a umidade do solo. Lá, desenvolvemos um sensor do tipo <em>DIY</em> (“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.</p>
<p>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:</p>
<ul>
<li><span>LM393 A0</span>: to NodeMCU A0 input</li>
<li><span>LM393 VCC</span>: to NodeMCU VCC or to NodeMCU GPIO D3*</li>
<li><span>LM393 GND</span>: to NodeMCU GND</li>
<li><span>LM393 D0</span>: Não conectado</li>
</ul>
<p><img class="lazy-img" src="https://cdn.instructables.com/FUD/2UB9/IU5NIPBH/FUD2UB9IU5NIPBH.MEDIUM.jpg" alt="NodeMCU WS V2.png"/></p>
<p>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.</p>
<p>* 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.</p>
<p>Uma rotina simples pode ser escrita para se ler a porta analógica:</p>
<p><span style="color: #993300;">/***************************************************</span><br/> <span style="color: #993300;">* Get Soil Moister Sensor data</span><br/> <span style="color: #993300;">**************************************************/</span><br/> <span style="color: #993300;">void getSoilMoisterData(void)</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> soilMoister = 0;</span><br/> <span style="color: #993300;"> digitalWrite (soilMoisterVcc, HIGH);</span><br/> <span style="color: #993300;"> delay (500);</span><br/> <span style="color: #993300;"> int N = 3;</span><br/> <span style="color: #993300;"> for(int i = 0; i < N; i++) // read sensor "N" times and get the average</span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> soilMoister += analogRead(soilMoisterPin);</span> <br/> <span style="color: #993300;"> delay(150);</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> digitalWrite (soilMoisterVcc, LOW);</span><br/> <span style="color: #993300;"> soilMoister = soilMoister/N;</span> <br/> <span style="color: #993300;"> Serial.println(soilMoister);</span><br/> <span style="color: #993300;"> soilMoister = map(soilMoister, 380, 0, 0, 100);</span> <br/> <span style="color: #993300;">}</span></p>
<pre><br/><br/>
Alguns comentários sobre a rotina acima:</pre>
<ul>
<li>Os dados do sensor é capturado 3 vezes, tirando-se uma média das mesmas.</li>
<li>Usamos MAP para configurar o intervalo em percentagem. Para definir os valores extremos, procedemos como abaixo:<ul>
<li>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</li>
<li>Colocar o higrômetro”no ar”, se observa que o valor exibido no Serial Monitor é em torno de 380.</li>
</ul>
</li>
</ul>
<p>Abaixo o código completo para esta fase do projeto:</p>
</div>
<div id="rich-embed-files" class="ible-files"></div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FTF/AZIS/IU5NIRN3/FTFAZISIU5NIRN3.ino" target="_blank"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="NodeMCU_DHT22_SM_Local_Station_OLED.ino"/><span class="title">NodeMCU_DHT22_SM_Local_Station_OLED.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step8" class="step-title">8: Subindo os dados para a nuvem: ThinkSpeak.com</h2>
<div class="step-body"><p>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! ;-)</p>
<p></p>
<p><img src="https://cdn.instructables.com/F8R/RDJQ/IU5NCV0T/F8RRDJQIU5NCV0T.MEDIUM.jpg" alt="Picture of Uploading the sensor data to ThinkSpeak.com"/></p>
<p>Comecemos!</p>
<ul>
<li>Primeiro você deve abrir uma conta no <a href="https://thingspeak.com/" target="_blank">ThinkSpeak.com</a></li>
<li>Siga as instruções para criar um canal e tome nota do seu <span>Channel ID</span>e<span> Write API Key</span></li>
<li>Atualize o código abaixo com as credenciais de sua rede Wi-Fi e Thinkspeak</li>
<li>Execute o programa no IDE</li>
</ul>
<p>Comentemos as partes mais importantes do código:</p>
<p>Primeiro:</p>
<ul>
<li>Incorporamos a biblioteca do ESP8266,</li>
<li>Definimos o cliente WiFi</li>
<li>Entramos com as credenciais do roteador WiFi e do Thingspeak :</li>
</ul>
<p><span style="color: #993300;">/* ESP12-E & Thinkspeak*/</span><br/> <span style="color: #993300;">#include <ESP8266WiFi.h></span><br/> <span style="color: #993300;">WiFiClient client;</span><br/> <span style="color: #993300;">const char* MY_SSID = "YOUR SSD ID HERE";</span><br/> <span style="color: #993300;">const char* MY_PWD = "YOUR PASSWORD HERE";</span><br/> <span style="color: #993300;">const char* TS_SERVER = "api.thingspeak.com";</span><br/> <span style="color: #993300;">String TS_API_KEY ="YOUR CHANNEL WRITE API KEY";</span></p>
<p></p>
<p>Segundo, incluamos uma nova biblioteca, muito importante em projetos de IoT: SimpleTimer.h:</p>
<p><span style="color: #993300;">/* TIMER */</span><br/> <span style="color: #993300;">#include <SimpleTimer.h></span><br/> <span style="color: #993300;">SimpleTimer timer;</span></p>
<p></p>
<p>Em terceiro lugar, durante o setup(), iniciar a comunicação serial, connectar o WiFi atarvés da função connectWiFi() e definir os temporizadores. Note-se que a linha de código: timer.setInterval (19000L, sendDataTS); chamará a função functionsendDataTS () a cada 19 segundos, a fim de transferir dados para o canal do ThinkSpeak.</p>
<p></p>
<p><span style="color: #993300;">void setup()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> ...</span><br/> <span style="color: #993300;"> Serial.begin(115200);</span><br/> <span style="color: #993300;"> delay(10);</span><br/> <span style="color: #993300;"> ...</span><br/> <span style="color: #993300;"> connectWifi();</span><br/> <span style="color: #993300;"> timer.setInterval(19000L, sendDataTS);</span><br/> <span style="color: #993300;"> ...</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p>Por último mas não menos importante, durante o loop (), a única ação necessária é iniciar o temporizador e pronto!</p>
<pre><br/>void loop() </pre>
<p><span style="color: #993300;">{</span><br/> <span style="color: #993300;">...</span><br/> <span style="color: #993300;">timer.run(); // Initiates SimpleTimer</span><br/> <span style="color: #993300;">}</span></p>
<pre><br/>Abaixo em detalhes, as duas funções utilizadas para se comunicar com o ThinkSpeak.com:</pre>
<p></p>
<p>ESP12-E conectando-se com a rede WiFi:</p>
<p></p>
<p><span style="color: #993300;">/***************************************************</span><br/> <span style="color: #993300;">* Connecting WiFi</span><br/> <span style="color: #993300;">**************************************************/</span><br/> <span style="color: #993300;">void connectWifi()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> Serial.print("Connecting to "+ *MY_SSID);</span><br/> <span style="color: #993300;"> WiFi.begin(MY_SSID, MY_PWD);</span><br/> <span style="color: #993300;"> while (WiFi.status() != WL_CONNECTED)</span> <br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> delay(1000);</span><br/> <span style="color: #993300;"> Serial.print(".");</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> Serial.println("");</span><br/> <span style="color: #993300;"> Serial.println("WiFi Connected");</span><br/> <span style="color: #993300;"> Serial.println("");</span> <br/> <span style="color: #993300;">}</span></p>
<p></p>
<p>ESP12-E enviando dados ao ThinkSpeak:</p>
<pre><br/><br/>
</pre>
<p>/<span style="color: #993300;">***************************************************</span><br/> <span style="color: #993300;">* Sending Data to Thinkspeak Channel</span><br/> <span style="color: #993300;">**************************************************/</span><br/> <span style="color: #993300;">void sendDataTS(void)</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> if (client.connect(TS_SERVER, 80))</span> <br/> <span style="color: #993300;"> {</span> <br/> <span style="color: #993300;"> String postStr = TS_API_KEY;</span><br/> <span style="color: #993300;"> postStr += "&field1=";</span><br/> <span style="color: #993300;"> postStr += String(temp);</span><br/> <span style="color: #993300;"> postStr += "&field2=";</span><br/> <span style="color: #993300;"> postStr += String(hum);</span><br/> <span style="color: #993300;"> postStr += "&field3=";</span><br/> <span style="color: #993300;"> postStr += String(soilMoister);</span><br/> <span style="color: #993300;"> postStr += "\r\n\r\n";</span></p>
<p><span style="color: #993300;"> client.print("POST /update HTTP/1.1\n");</span><br/> <span style="color: #993300;"> client.print("Host: api.thingspeak.com\n");</span><br/> <span style="color: #993300;"> client.print("Connection: close\n");</span><br/> <span style="color: #993300;"> client.print("X-THINGSPEAKAPIKEY: " + TS_API_KEY + "\n");</span><br/> <span style="color: #993300;"> client.print("Content-Type: application/x-www-form-urlencoded\n");</span><br/> <span style="color: #993300;"> client.print("Content-Length: ");</span><br/> <span style="color: #993300;"> client.print(postStr.length());</span><br/> <span style="color: #993300;"> client.print("\n\n");</span><br/> <span style="color: #993300;"> client.print(postStr);</span><br/> <span style="color: #993300;"> delay(1000);</span> <br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> sent++;</span><br/> <span style="color: #993300;"> client.stop();</span><br/> <span style="color: #993300;">}</span></p>
<pre><br/><br/>
</pre>
<pre><span>/</span><a href="http://www.instructables.com/files/orig/F0B/FTEB/IU5NEQQR/F0BFTEBIU5NEQQR.ino" target="_blank"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="NodeMCU_Weather_Station_TS_Blog.ino"/><span class="title">NodeMCU_Weather_Station_TS_Blog.ino</span></a></pre>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step9" class="step-title">9: Introduzindo o BLYNK</h2>
<div id="photoset-SK8GGRLIU5NJ25D" class="photoset"> Mas o que é BLYNK? Pelo<a href="http://www.blynk.cc/" target="_blank"> Blynk website</a> podemos entender que :</div>
<div class="step-body"><blockquote><p>Blynk é uma plataforma baseada em Apps para iOS e Android, utilizada para controlar-se Arduino, Raspberry Pi e outros dispositivos através da Internet. É um painel digital (“Dashboard”) onde você pode construir uma interface gráfica para o seu projeto, simplesmente arrastando e soltando “widgets”.</p>
</blockquote>
<p>É realmente muito fácil desenvolver projectos de IoT utilizando-se o BLYNK.</p>
<p>Para começar, aprendamos a controlar nosso velho LED conectado a porta D7, utilisando-se de um smartphone. Para isso, sigamos os passos abaixo:</p>
<ul>
<li>Baixar o BLYNK app para o <a href="https://itunes.apple.com/us/app/blynk-control-arduino-raspberry/id808760481?ls=1&mt=8" target="_blank">iPhone da Apple</a> ou o <a href="https://play.google.com/store/apps/details?id=cc.blynk" target="_blank">Google Android</a></li>
<li>Instale a <a href="https://github.com/blynkkk/blynk-library/releases/tag/v0.3.10" target="_blank">Biblioteca do BLYNK para Arduino</a>. Note que você vai baixar um arquivo zip (Há 5 arquivos lá que você deverá instalar manualmente em sua Biblioteca do Arduino).</li>
<li>Uma vez que o Arduino IDE é recarregado, abra o sketch: Exemples ==> Blynk ==> Boards_WiFi ==> ESP8266_Standalone</li>
</ul>
<br/>
<p><span style="color: #993300;">#define BLYNK_PRINT Serial // Comment this out to disable prints and save space</span><br/> <span style="color: #993300;">#include <ESP8266WiFi.h></span><br/> <span style="color: #993300;">#include <BlynkSimpleEsp8266.h></span></p>
<p><span style="color: #993300;">// You should get Auth Token in the Blynk App.</span><br/> <span style="color: #993300;">// Go to the Project Settings (nut icon).</span><br/> <span style="color: #993300;">char auth[] = "YourAuthToken";</span></p>
<p><span style="color: #993300;">// Your WiFi credentials.</span><br/> <span style="color: #993300;">// Set password to "" for open networks.</span><br/> <span style="color: #993300;">char ssid[] = "YourNetworkName";</span><br/> <span style="color: #993300;">char pass[] = "YourPassword";</span></p>
<p><span style="color: #993300;">void setup()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> Serial.begin(9600);</span><br/> <span style="color: #993300;"> Blynk.begin(auth, ssid, pass);</span><br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> Blynk.run();</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p>O código acima é basicamente tudo o que você precisa instalar em seu ESP12-E para executar seus projetos de IoT com o BLYNK. Não se esqueça de alterar a velocidade de comunicação para 115.200 bauds e entrar com as credenciais de seu roteador local e de seu projeto no BLYNK.</p>
<p>Agora, vamos abrir o aplicativo “Blynk” no smartphone:</p>
<p></p>
<img class="alignnone wp-image-7369" src="https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=830&h=223" alt="blynk_led_ctrl" width="830" height="223"/><a href="https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=1660&h=444">https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=1660&h=444</a> 1660w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=150&h=40">https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=150&h=40</a> 150w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=300&h=80">https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=300&h=80</a> 300w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=768&h=205">https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=768&h=205</a> 768w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=1024&h=274">https://mjrobot.files.wordpress.com/2016/10/blynk_led_ctrl.png?w=1024&h=274</a> 1024w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /><ol>
<li>Clique na tela <span>Create New Project</span></li>
<li>De um nome para seu projeto (Por exemplo: “LED Control”)</li>
<li>Selecione o HW apropriado: <span>NodeMCU</span></li>
<li>Anote seu código do <span>Authorization Token</span> (você pode enviar-lo por e-mail e copiar-lo no código anterior:<pre><span style="color: #993300;">char auth[] = "YourAuthToken";</span></pre>
</li>
<li>Pressione <span>OK</span>. Uma tela vazia cheia de pontos irá aparecer.</li>
<li>Clique na tela para abrir o <span>Widget Box</span></li>
<li>Adicione o <span>Button widget</span>.</li>
<li>Clique no ícone do botão para abrir o <span>Widget Settings</span>. A principal coisa a definir é o <span>PIN number</span> (Como nosso LED está conectado ao pino D7 – escolha <span>pin D7</span>). É bom dar um nome para o widget: “LED”. Pressione <span>OK</span></li>
<li>Caso ainda não o tenha feito, volte para o seu código e atualize-o com o código de autorização que você obteve no aplicativo:<span> <em>char auth[] = “YourAuthToken”;</em></span></li>
</ol>
<p>Uma vez que o código seja carregado em seu ESP12-E e o programa seja executado, o Serial Monitor deve apresentar algo semelhante ao meu abaixo:</p>
<p><img class="alignnone size-full wp-image-7823" src="https://mjrobot.files.wordpress.com/2016/10/blynk-serial-monitor.png?w=840" alt="blynk-serial-monitor"/><a href="https://mjrobot.files.wordpress.com/2016/10/blynk-serial-monitor.png?w=150">https://mjrobot.files.wordpress.com/2016/10/blynk-serial-monitor.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk-serial-monitor.png?w=300">https://mjrobot.files.wordpress.com/2016/10/blynk-serial-monitor.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk-serial-monitor.png?w=768">https://mjrobot.files.wordpress.com/2016/10/blynk-serial-monitor.png?w=768</a> 768w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></p>
<p>Agora basta executar o projecto Blynk (use o botão “play” no canto superior direito do aplicativo em seu smartphone) e isto é tudo! Você estará controlando seu HW através da Internet !!!!! </p>
<p><img class="alignnone size-full wp-image-7833" src="https://mjrobot.files.wordpress.com/2016/10/blynk_led.png?w=840" alt="Blynk_LED.png"/><a href="https://mjrobot.files.wordpress.com/2016/10/blynk_led.png?w=150">https://mjrobot.files.wordpress.com/2016/10/blynk_led.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk_led.png?w=300">https://mjrobot.files.wordpress.com/2016/10/blynk_led.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk_led.png?w=768">https://mjrobot.files.wordpress.com/2016/10/blynk_led.png?w=768</a> 768w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></p>
</div>
</div>
<div class="step-container"><h2 id="step10" class="step-title">10: Running our Weather Station on Blynk</h2>
<div class="step-body"><p>Podemos também enviar os dados que estamos coletando de sensores para o Blynk, da mesma maneira que fizemos com o ThingSpeak.</p>
<p>Criemos um novo projeto Blink em nosso aplicativo (ou atualizar o que já foi criado):</p>
<p><img class="alignnone size-full wp-image-7379 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=840" alt="Blynk 2.png"/><a href="https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=1680">https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=1680</a> 1680w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=150">https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=150</a> 150w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=300">https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=300</a> 300w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=768">https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=768</a> 768w, <a href="https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=1024">https://mjrobot.files.wordpress.com/2016/10/blynk-2.png?w=1024</a> 1024w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></p>
<ol>
<li>Clique na tela e crie 3 novos Widgets. Em nosso caso: <span>“Gauge”</span></li>
<li>Para cada um desses widgets, defina: <span>name</span>, <span>input type, range</span> e <span>frequency </span>para atualização dos dados</li>
</ol>
<p>Para os nossos sensores, definamos os seguintes “Virtual Ports”:</p>
<ul>
<li>V10: Temperature, range 0-50oC, 5s of pooling frequency</li>
<li>V11: Humidity, range 0-100%, 5 s</li>
<li>V12: Soil Moisture, range 0-100%, 5 s</li>
</ul>
<p>Em nosso código para o ESP12-E teremos de introduzir os valores acima. Comecemos a partir do código anterior e adicionemos os novos sensores e timer. A linha abaixo de código incluída no <em><span>setup ()</span></em>, da mesma maneira que vimos com a versão Thinkspeak, forçará o programa para executar a função <em><span>sendUptime ()</span> </em>a cada 5 segundos.</p>
<pre><span><span style="color: #993300;"> timer.setInterval(5000L, sendUptime);</span> </span></pre>
<p></p>
<p>Abaixo a função completa:</p>
<p><span style="color: #993300;">/***************************************************</span><br/> <span style="color: #993300;">* Send DHT data to Blynk</span><br/> <span style="color: #993300;">**************************************************/</span><br/> <span style="color: #993300;">void sendUptime()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> // You can send any value at any time.</span><br/> <span style="color: #993300;"> // Please don't send more that 10 values per second.</span><br/> <span style="color: #993300;"> Blynk.virtualWrite(10, temp); //virtual pin V10</span><br/> <span style="color: #993300;"> Blynk.virtualWrite(11, hum); // virtual pin V11</span><br/> <span style="color: #993300;"> Blynk.virtualWrite(12, soilMoister); // virtual pin V12</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p>E, Voilá! O seu aplicativo Blynk estará recebendo informações atualizadas a respeito de seus sensores e você também poderá controlar o LED pela internet.</p>
<pre><br/><br/>
</pre>
<p><img class="lazy-img" src="https://cdn.instructables.com/FEG/G9Y9/IU5NJX00/FEGG9Y9IU5NJX00.SMALL.jpg" alt="FullSizeRender 27.jpg" width="563" height="596"/></p>
<p>Abaixo o código completo para nosso <em><span>Blynk Weather Station Control app</span></em>:</p>
</div>
<div id="rich-embed-files" class="ible-files"></div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/F9S/01KU/IU5NJXSL/F9S01KUIU5NJXSL.ino" target="_blank"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="BLYNK_NodeMCU_Weather_Station.ino"/><span class="title">BLYNK_NodeMCU_Weather_Station.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step11" class="step-title">11: Utilizando-se o Blynk e o ThinkSpeak simultaneamente</h2>
<div id="photoset-SV8VYDBIU5NJYG3" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="http://www.instructables.com/file/FW66RSWIU5NK1WY/" target="_blank"><img src="https://cdn.instructables.com/FW6/6RSW/IU5NK1WY/FW66RSWIU5NK1WY.MEDIUM.jpg" alt="Picture of Running Blynk and ThinkSpeak simustanealy "/></a></div>
</div>
</div>
</div>
<div class="step-body"><p>É claro que podemos ter nossos dados em ambas plataformas:</p>
<ul>
<li>Blynk app (que é ótimo para o controle e mobilidade) e</li>
<li>ThinkSpeak que é muito bom para armazenamento de histórico e análise de dados.</li>
</ul>
<p>NOTA: O Blynk possui um Widget: <a href="http://docs.blynk.cc/#widgets-other-webhook" target="_blank">Webhook</a>, onde voce pode comandar o envio automático dos dados ao ThinkSpeak sem necessidade de código adicional. O problema é que este widget só está disponível para Android. Assim fica aqui o código para fazer-lo por SW.</p>
<p>O arquivo abaixo mostra o código completo:</p>
</div>
<div id="rich-embed-files" class="ible-files"></div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/F1E/J9RB/IU5NK2M2/F1EJ9RBIU5NK2M2.ino" target="_blank"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="NodeMCU_Weather_Station_Blynk_TS_Blog.ino"/><span class="title">NodeMCU_Weather_Station_Blynk_TS_Blog.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 id="step12" class="step-title">Conclusão</h2>
<p><a width="300" href="http://storage.ning.com/topology/rest/1.0/file/get/1979596529?profile=RESIZE_320x320" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979596529?profile=RESIZE_320x320" class="align-full"/></a></p>
<div class="step-body"><p>Como sempre, espero que este projeto ajude outras pessoas a encontrar seu caminho no apaixonante mundo da eletrônica e do IoT!</p>
<p>Para mais projetos, visite meu blog aqui no Garagem ou no <a href="http://mjrobot.org" target="_blank">MJRoBot.org</a></p>
<p>Um abraço e até o próximo post!</p>
<p>Obrigado</p>
<p class="p2"><span class="s1">Saludos desde o sul do mundo!</span></p>
<p class="p2">Marcelo</p>
</div>
</div>ArduFarmBot: Controlando um tomateiro com a ajuda de um Arduino e Internet das coisas (IoT)tag:labdegaragem.com,2016-09-05:6223006:BlogPost:5623582016-09-05T13:30:00.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="step-container"><div class="photoset" id="photoset-S1JY09GIRXT9PWY"><div class="photoset-row cols-3"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="http://www.instructables.com/file/FS3ASU2ISCAWZ58/"><br class="Apple-interchange-newline"></br></a><a href="https://mjrobot.files.wordpress.com/2016/08/robotomato2.png?w=698&h=1&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2016/08/robotomato2.png?w=698&h=1&crop=1&width=703" width="703"></img></a></div>
</div>
</div>
</div>
</div>
<div class="step-container"><div id="photoset-S1JY09GIRXT9PWY" class="photoset"><div class="photoset-row cols-3"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="http://www.instructables.com/file/FS3ASU2ISCAWZ58/"><br class="Apple-interchange-newline"/></a><a href="https://mjrobot.files.wordpress.com/2016/08/robotomato2.png?w=698&h=1&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/robotomato2.png?w=698&h=1&crop=1&width=703" width="703" class="align-full"/></a><a class="photoset-link" href="http://www.instructables.com/file/FS3ASU2ISCAWZ58/"></a></div>
</div>
</div>
</div>
<div class="step-body"><p class="p1"><span>O objectivo deste projecto criado a 4 mãos juntamente com meu amigo Maurício Pinto, é o de se conseguir uma plantação de tomates totalmente automatizada, onde também se pode monitorar pela internet informações tais como temperatura, humidade do solo, luminosidade, etc.</span></p>
<img src="https://cdn.instructables.com/FS3/ASU2/ISCAWZ58/FS3ASU2ISCAWZ58.SMALL.jpg?width=267" width="367" class="align-left" height="489"/><br/>
<p class="p1">Neste tutorial desenvolveremos um controlador eletrônico (o “ArduFarmBot”) que a partir da captura de dados provenientes de uma plan</p>
<p class="p1">tação de tomates (vulgo tomateiro), tais como temperatura, umidade relativa do ar, luminosidade e umidade do solo, decidirá autonomamente a quantidade certa (e quando) o plantio deve receber calor e irrigação (água + nutrientes). Além disso, o ArduFarmBot permitirá a intervenção manual de um operador (tanto de forma local quanto remotamente via Internet), a fim de controlar o acionamento de uma bomba de água e de uma lâmpada elétrica (esta última para ser usada na ger</p>
<p class="p1">ação de calor para as plantas).</p>
<p class="p1"><span class="s1">Em suma, o ArduFarmBot receberá como entrada:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">Sensores (dados analógicos):</span><ul class="ul1">
<li class="li1"><span class="s1">Temperatura</span></li>
<li class="li1"><span class="s1">Umidade do ar</span></li>
<li class="li1"><span class="s1">Luminosidade</span></li>
<li class="li1"><span class="s1">Umidade do solo</span></li>
</ul>
</li>
</ul>
<p class="p1"><span class="s1">E fornecerá como saídas:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">Atuadores:</span><ul class="ul1">
<li class="li1"><span class="s1">Relé para controle de bomba</span></li>
<li class="li1"><span class="s1">Relé para controlo da lâmpada</span></li>
</ul>
</li>
<li class="li1"><span class="s1">Sinalização (dados digitais):</span><ul class="ul1">
<li class="li1"><span class="s1">Visual e sonoro para indicação de status / erro</span></li>
<li class="li1"><span class="s1">Visual de Estado da bomba</span></li>
<li class="li1"><span class="s1">Visual para o estado da lâmpada</span></li>
</ul>
</li>
<li class="li1"><span class="s1">Display dos dados</span><ul class="ul1">
<li class="li1"><span class="s1">Todos os dados analógicos e digitais devem estar disponíveis para avaliação instantânea</span></li>
</ul>
</li>
<li class="li1"><span class="s1">Armazenamento de dados</span><ul class="ul1">
<li class="li1"><span class="s1">Dados históricos deve ser de armazenamento remotamente na internet e opcionalmente também localmente (via cartão de memória).</span></li>
</ul>
</li>
</ul>
<p class="p1"><span class="s1">O diagrama de blocos abaixo mostra os principais componentes do projeto.</span></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/08/newblockdiagram.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/newblockdiagram.png?w=840&width=703" width="703" class="align-full"/></a></p>
<p class="p1"><span class="s1">O vídeo abaixo descreve os principais elementos utilizados no primeiro protótipo de laboratório usado para testes:</span></p>
<p class="p1"><span class="s1"><a class="ytp-share-panel-link ytp-no-contextmenu" target="_blank" href="https://youtu.be/SwgKzfAvWlI">https://youtu.be/SwgKzfAvWlI</a></span></p>
<p class="p1"></p>
<p class="p1"><span class="s1">Neste segundo vídeo, mostramos como os comandos funcionarão em modo local e remotamente via Web page:</span></p>
<div class="jetpack-video-wrapper"><a class="ytp-share-panel-link ytp-no-contextmenu" target="_blank" href="https://youtu.be/fcRA6g8ZGS8">https://youtu.be/fcRA6g8ZGS8</a></div>
<p class="p1"></p>
</div>
<div id="gpt-ad-native-middle" class="gpt-ad"></div>
</div>
<div class="step-container"><h1 class="step-title">PARTE 1 – ESTAÇÃO LOCAL</h1>
<p class="p1"><span class="s1">O projeto será dividido em 3 partes:</span></p>
<ol class="ol1">
<li class="li1"><span class="s1">Estação local</span></li>
<li class="li1"><span class="s1">Estação Remota ( ESP8266, Thingspeak, criação da página web em HTML/CSS/JS, etc)</span></li>
<li class="li1"><span class="s1">Uso e Acompanhamento do ArduFarmBot em uma plantação real. </span></li>
</ol>
<p class="p1">Aqui nesta primeira parte, vamos explorar a estação local, desenvolvendo o HW e o SW para trabalhar com os sensores, atuadores, aprendendo como exibir dados, etc.</p>
<p class="p1">Abaixo o diagrama em blocos simplificado da versão 1 da estação local:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/08/localstationblockdiagram.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/localstationblockdiagram.png?w=840&width=703" width="703" class="align-full"/></a></p>
<h2 class="p1"><span class="s1">1.1: Lista de Materiais</span></h2>
<div id="photoset-S37PEFQIRXT9UGY" class="photoset"><div class="photoset-row cols-1"></div>
<div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a href="https://mjrobot.files.wordpress.com/2016/08/fullcomponents.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/fullcomponents.png?w=840&width=703" width="703" class="align-full"/></a></div>
<div class="photoset-item photoset-image"><p class="p1"><span class="s1">Os principais componentes para o ArduFarmBot são (valores em USD):</span></p>
<p><span class="s1">Itens gerais (cerca de $ 37,00):</span></p>
<ul>
<li class="li2"><a href="https://www.amazon.com/OSOYOO-ATMEGA328P-Module-Micro-controller-Arduino/dp/B00UACD13Q/ref=sr_1_4?ie=UTF8&qid=1471642878&sr=8-4&keywords=arduino+nano"><span class="s2">Arduino Nano</span></a><span class="s3"> – ( $ 7,50)</span></li>
<li class="li3"><span class="s4"><a href="https://www.amazon.com/Vktech-Appliance-Temperature-Humidity-Measurement/dp/B00O8RIYYU/ref=sr_1_1?ie=UTF8&qid=1471643027&sr=8-1&keywords=dht22"><span class="s2">Sensor de Temperatura e Umidade DHT22</span></a></span><span class="s5"> – ($ 3,66)</span></li>
<li class="li3"><span class="s4"><a href="https://wholesaler.alibaba.com/product-detail/AD-018-Photoresistor-Optosensor-Photo-Resistor_1869567604.html?spm=a2700.7724838.0.0.T4EILH"><span class="s2">Sensor Luminosidade – AD-018 módulo photo-resistor.</span></a></span><span class="s5"> , ou equivalente – ($ 0,71)</span></li>
<li class="li1"><span class="s6"><a href="https://www.amazon.com/Keyes-Soil-moisture-sensor/dp/B013GCAQH0/ref=sr_1_12?s=pc&ie=UTF8&qid=1471697625&sr=1-12&keywords=Soil+Moisture+Sensor"><span class="s2">Soil Moisture Sensor</span></a></span><span class="s1"> – ($ 1,99) (Opcionalmente, pode ser do tipo “DIY” vide capítulo 1.5)</span></li>
<li class="li2"><span class="s2"><a href="https://www.amazon.com/SainSmart-Serial-Module-Shield-Arduino/dp/B0080DYTZQ/ref=pd_bxgy_147_img_2?ie=UTF8&psc=1&refRID=1SFJEH41VDGG9PFDDP07">LCD 20X4 I2C</a></span><span class="s3"> ($ 13,99)</span></li>
<li class="li2"><a href="https://www.amazon.com/Gikfun-12x12x7-3-Tactile-Momentary-Arduino/dp/B01E38OS7K/ref=sr_1_2?s=pc&ie=UTF8&qid=1471698363&sr=1-2&keywords=buttons+arduino"><span class="s2">Botões (2X)</span></a><span class="s3"> – ($ 0.90)</span></li>
<li class="li2"><a href="https://www.amazon.com/TOOGOO-Yellow-Assorted-Emitting-Diodes/dp/B00E34MNYU/ref=sr_1_1?s=pc&ie=UTF8&qid=1471698298&sr=1-1&keywords=LEDs"><span class="s2">LEDs (3x)</span></a><span class="s3"> ($ 0.20)</span></li>
<li class="li3"><span class="s4"><a href="https://www.amazon.com/Diymall%C2%AE-Esp8266-Serial-Wireless-Transceiver/dp/B00O34AGSU/ref=sr_1_2?s=pc&ie=UTF8&qid=1471698562&sr=1-2&keywords=esp+8266"><span class="s2">Esp8266 Serial WiFi Transceiver Module Esp-01</span></a></span><span class="s5"> – ($ 5,96) – (Para ser usado na parte 2)</span></li>
<li class="li1"><span class="s6"><a href="https://wholesaler.alibaba.com/product-detail/Hot-Sale-3-3-5V-PCB_60391191771.html?spm=a2700.7782932.0.0.OSQzM6"><span class="s2">Buzzer (ativo) – Ky-12</span></a></span><span class="s1"> ou equivalente ($ 0,60) – (Para ser usado na parte 2)</span></li>
<li class="li1"><span class="s1">2 X <a href="https://www.amazon.com/Tolako-Module-Arduino-Official-Boards/dp/B00VRUAHLE/ref=sr_1_2?s=electronics&ie=UTF8&qid=1471814741&sr=1-2&keywords=arduino+relay"><span class="s7">5v Módulo de Relé</span></a> ($ 11,60)</span></li>
<li class="li3"><span class="s4"><a href="https://www.amazon.com/dp/B01EV70C78?psc=1"><span class="s2">Fios de salto</span></a></span><span class="s5"> (S1.00)</span></li>
<li class="li1"><span class="s1">10 Kohm resistor – ($ 0,03)</span></li>
<li class="li1"><span class="s1">2.2 Kohm resistor – ($ 0,03)</span></li>
<li class="li1"><span class="s1">1.0 Kohm resistor – ($ 0,03)</span></li>
<li class="li1"><span class="s1">220 ohm resistor – ($ 0,03)</span></li>
</ul>
<p><span class="s1">Opção 1 com Nano Shield (em torno de US $ 15,00):</span></p>
<ul class="ul1">
<li class="li3"><span class="s4"><a href="https://www.amazon.com/Multi-Function-Funduino-Shield-Sensor-Expansion/dp/B013JMBSUG/ref=sr_1_1?ie=UTF8&qid=1471642946&sr=8-1&keywords=arduino+nano+shield+funduino"><span class="s2">Shield Arduino Nano ( “Funduino”)</span></a></span><span class="s5"> – ($ 7,28)</span></li>
<li class="li3"><span class="s4"><a href="https://www.amazon.com/Matrix-Membrane-Switch-Plastic-Keyboard/dp/B00HR8N1C2/ref=sr_1_8?s=electronics&ie=UTF8&qid=1472307738&sr=1-8&keywords=membrane"><span class="s2">Teclado de membrana (4 teclas)</span></a></span><span class="s5"> – ($ 6,65)</span></li>
<li class="li1"><span class="s6"><span class="s2"><a href="https://www.amazon.com/Points-Solderless-Prototype-Breadboard-Arduino/dp/B01EFIHII4/ref=sr_1_3?s=electronics&ie=UTF8&qid=1472308074&sr=1-3&keywords=mini+breadboard">Placa de ensaio Mini</a></span></span><span class="s1"> ($ 1,00) (Para ser usado na parte 2)</span></li>
</ul>
</div>
</div>
</div>
</div>
<div class="step-body"><p class="p1"><span class="s1">Opção 2 sem o Shield para o Nano- (cerca de US $ 4,00):</span></p>
<ul class="ul1">
<li class="li1"><span class="s2"><a href="https://www.amazon.com/gp/product/B01B034F7O/ref=ox_sc_act_title_4?ie=UTF8&psc=1&smid=A3GQ2RR1HCHKCZ"><span class="s3">3.3V Voltage Regulator LD33V</span></a></span><span class="s1"> ou equivalente ($ 1.20) (Para ser usado na parte 2)</span></li>
<li class="li1"><span class="s1">Capacitor – electrolítico 10uF (2X) para ser utilizado com LD33V – ($ 0,10)</span></li>
<li class="li2"><span class="s4"><a href="https://www.amazon.com/Frentaly%C2%AE-Solderless-BreadBoard-tie-points-power/dp/B01258UZMC/ref=pd_sim_23_1?ie=UTF8&psc=1&refRID=VBPNAM9C2C0452PYCAQM">Placa de ensaio</a> – Média</span><span class="s5"> – (US $ 2,50)</span></li>
</ul>
</div>
</div>
<div class="step-container"><h2 class="p1"><span class="s1">1.2: Instalação, programação e teste dos sensores</span></h2>
<div class="step-body"><div><div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/09/02/ardufarmbot-controlando-um-tomateiro-com-a-ajuda-de-um-arduino-e-internet-das-coisas-iot/img_4702/"><img src="https://mjrobot.files.wordpress.com/2016/08/img_4702.jpg?w=442&h=332&crop=1" width="442" height="332" title="IMG_4702" alt="IMG_4702"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/09/02/ardufarmbot-controlando-um-tomateiro-com-a-ajuda-de-um-arduino-e-internet-das-coisas-iot/ardufarmbot_sensors_diagram/"><img src="https://mjrobot.files.wordpress.com/2016/08/ardufarmbot_sensors_diagram.png?w=390&h=332&crop=1" width="390" height="332" title="ArduFarmBot_Sensors_Diagram" alt="ArduFarmBot_Sensors_Diagram"/></a></div>
</div>
</div>
</div>
<h4><span class="font-size-3">SENSOR DE TEMPERATURA E HUMIDADE: DHT 22 (OR DHT11)</span></h4>
</div>
<p class="p1"><span class="s1">O primeiro sensor a ser testado e instalado é o DHT 22, 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. </span></p>
<p class="p1"><span class="s1">De acordo com a sua <span class="s2"><a href="https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf">folha de dados</a>(Datasheet)</span>, 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).</span></p>
<p class="p1"><span class="s1">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: <a href="https://learn.adafruit.com/dht"><span class="s2">Tutorial DHT22 / 11</span></a> .</span></p>
<p class="p1"><span class="s1">O DHT22 tem 4 pinos (de frente para o sensor, o pino 1 é o mais esquerda):</span></p>
<ol class="ol1">
<li class="li1"><span class="s1">VCC (3 a 5V)</span></li>
<li class="li1"><span class="s1">saída de dados</span></li>
<li class="li1"><span class="s1">Não conectado</span></li>
<li class="li1"><span class="s1">GND (Terra)</span></li>
</ol>
<p class="p1"><span class="s1">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 D5 do Arduino (veja o diagrama acima).</span></p>
<p class="p1"><span class="s1">Uma vez que o sensor é instalado fisicamente no Arduino, baixe a biblioteca DHT a partir do repositório de programas: <a href="https://github.com/adafruit/DHT-sensor-library"><span class="s2">Adafruit github</span></a> e a instale junto as outras bibliotecas de seu IDE (ambiente de desenvolvimento de programas do Arduino).</span></p>
<p class="p1"><span class="s1">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:</span></p>
<p></p>
<p><span style="color: #993300;">/****************************************************************</span><br/> <span style="color: #993300;">* DHT Sensor - Setup and Test</span><br/> <span style="color: #993300;">* Based on the original code written by ladyada, public domain</span><br/> <span style="color: #993300;">* MJRoBot 21Aug16</span><br/> <span style="color: #993300;">****************************************************************/</span><br/> <span style="color: #993300;">// Include DHT Library</span><br/> <span style="color: #993300;">#include <DHT.h></span></p>
<p><span style="color: #993300;">// Sensor defiitions</span><br/> <span style="color: #993300;">#define DHTPIN 5 // DHT data pin connected to Arduino pin 5</span><br/> <span style="color: #993300;">#define DHTTYPE DHT22 // DHT 22 (if your sensor is the DHT 11, only change this line by: #define DHTTYPE DHT11)</span></p>
<p><span style="color: #993300;">// Variables to be used by Sensor</span><br/> <span style="color: #993300;">float tempDHT; // on the final program we will use int insteady of float. No need for high precision measurements</span> <br/> <span style="color: #993300;">float humDHT;</span><br/> <span style="color: #993300;">float hic; // only used here for testing purposes</span></p>
<p><span style="color: #993300;">// Initialize the DHT sensor</span><br/> <span style="color: #993300;">DHT dht(DHTPIN, DHTTYPE);</span></p>
<p><span style="color: #993300;">void setup()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> Serial.begin(9600);</span> <br/> <span style="color: #993300;"> Serial.println("DHT 22 Setup & Test");</span><br/> <span style="color: #993300;"> dht.begin();</span><br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> // Wait a few seconds between measurements.</span><br/> <span style="color: #993300;"> delay(2000);</span></p>
<p><span style="color: #993300;"> //Read temperature and humidity values from DHT sensor:</span><br/> <span style="color: #993300;"> tempDHT = dht.readTemperature();</span> <br/> <span style="color: #993300;"> humDHT = dht.readHumidity();</span></p>
<p><span style="color: #993300;"> // Check if any reads failed and exit early (to try again).</span><br/> <span style="color: #993300;"> if (isnan(humDHT) || isnan(tempDHT))</span> <br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> Serial.println("Failed to read from DHT sensor!");</span><br/> <span style="color: #993300;"> return;</span><br/> <span style="color: #993300;"> }</span></p>
<p><span style="color: #993300;"> // Compute heat index in Celsius (isFahreheit = false)</span><br/> <span style="color: #993300;"> float hic = dht.computeHeatIndex(tempDHT, humDHT, false);</span></p>
<p><span style="color: #993300;"> // Show measurements at Serial monitor:</span><br/> <span style="color: #993300;"> Serial.print(" Temp DHT ==> ");</span><br/> <span style="color: #993300;"> Serial.print(tempDHT);</span><br/> <span style="color: #993300;"> Serial.print("oC Hum DHT ==> ");</span><br/> <span style="color: #993300;"> Serial.print(humDHT);</span><br/> <span style="color: #993300;"> Serial.print("% Heat index: ");</span><br/> <span style="color: #993300;"> Serial.print(hic);</span><br/> <span style="color: #993300;"> Serial.println(" oC ");</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p><span class="font-size-3">Sensor de Luminosidade (LDR)</span></p>
<p>Com o DHT funcionando, é hora de instalar e testar o sensor de luminosidade. Para isso, podemos usar um simples LDR (Resistor variável com luz). Basicamente, o que se deve fazer é criar um divisor de tensão, onde um dos resistores é o LDR e o outro um fixo, sendo o “ponto médio do divisor” conectado a uma entrada analógica do Arduino. Desta forma, variando-se a luz, a resistência LDR variará proporcionalmente e por conseguinte , a tensão no ponto do meio do divisor também vai variar.</p>
<div><p class="p2"><span class="s1">Em nosso projeto, por facilidade de instalação, usaremos um módulo LDR barato (KY18) o qual já possui o divisor de tensão integrado. O módulo tem 3 pinos ( “S” para dados; “+” para VCC e “-” para GND). O pino “S” será ligado ao pino analógico Ao do Arduino. O “+” e “-” pinos devem ser ligadas, respectivamente, a 5 V e GND. Se o consumo de energia é uma preocupação, o “+” pode ser conectado a uma das saídas digitais do Arduino, que deverá ser colocada em “HIGH” alguns milésimos de segundo antes de se ler a tensão no pino A0, retornando para “LOW” depois disso.</span></p>
<p class="p2"><span class="s1">A função <span><span><i>getLumen (LDR_PIN)</i></span></span> lerá algumas vezes a saída do sensor (poderia ser de 3, 10 ou mais, você decide o que é melhor para o seu caso) calculando a média dessas leituras (isso para diminuir o risco que uma uma única leitura seja na verdade um ruído). Além disso, uma vez que a saída do conversor analógico digital (ADC) interno do Arduino será um número de 0 a 1023, deveremos “mapear” esses valores, a fim de obter os seguintes resultados como porcentagens:</span></p>
<ul class="ul1">
<li class="li2"><span class="s1">“Dark Full” ==> saída ADC: 1023 ==> 0%</span></li>
<li class="li2"><span class="s1">“Full Light” ==> saída ADC: 0 ==> 100%</span></li>
</ul>
<p>Abaixo a função em C++:</p>
<p></p>
</div>
<p><span style="color: #993300;">int getLumen(int anaPin)</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> int anaValue = 0;</span><br/> <span style="color: #993300;"> for(int i = 0; i < 10; i++) // read sensor 10X ang get the average</span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> anaValue += analogRead(anaPin);</span> <br/> <span style="color: #993300;"> delay(50);</span><br/> <span style="color: #993300;"> }</span></p>
<p><span style="color: #993300;"> anaValue = anaValue/10; //Light under 300; Dark over 800</span><br/> <span style="color: #993300;"> anaValue = map(anaValue, 1023, 0, 0, 100); //LDRDark:0 ==> light 100%</span></p>
<p><span style="color: #993300;"> return anaValue;</span> <br/> <span style="color: #993300;">}</span></p>
<p><span class="font-size-3">Sensor de Humidade de solo (Higrômetro)</span></p>
<div><p class="p2"><span class="s1">Um sensor para testar a umidade do solo (ou higrômetro) é muito simples. Ele possui o mesmo princípio de funcionamento que o sensor de luminosidade. Um divisor de tensão será usado como ponto de entrada de uma das portas analógicas do Arduino, mas em vez de um resistor que varie com luz, usaremos um que varie com a humidade do solo. O circuito básico é muito simples e pode ser visto abaixo.</span></p>
</div>
<p><img src="https://cdn.instructables.com/F2J/2T4V/IRXTM5LC/F2J2T4VIRXTM5LC.MEDIUM.jpg" alt="Picture of Installing, programing and testing the sensors "/></p>
<p class="p1"><span class="s1">Infelizmente, a realidade é um pouco mais complexa do que isso (mas não muito). Um simples sensor como o descrito funcionaría bem, mas não por muito tempo. O problema é que ter uma corrente constante fluindo através dos eletrodos em uma única direção gerará corrosão sobre eles, devido ao efeito de eletrólise. Uma maneira de resolver isso é conectar-se os eletrodos não diretamente ao VCC e terra, mas à portas digitais do Arduino (por exemplo VCC a D7 e GND a D6 como mostrado acima). Ao fazer isso, em primeiro lugar o sensor seria “energizado” apenas quando a leitura realmente ocorresse e a direção da corrente sobre as sondas poderia ser alternada, eliminando o efeito da eletrólise.</span></p>
<p class="p1"><span class="s1">Abaixo um código de teste simples, baseada no post <a href="http://forum.arduino.cc/index.php?topic=37975.0"><span class="s2">“How to: Soil Moisture Measurement?”</span></a> :</span></p>
<p><span style="color: #993300;">/****************************************************</span> <br/> <span style="color: #993300;">Soil Moisture Sensor Test</span><br/> <span style="color: #993300;">****************************************************/</span><br/> <span style="color: #993300;">#define SOIL_MOIST_PIN 1 // used for Soil Moisture Sensor Input</span><br/> <span style="color: #993300;">#define SMS_VCC 7</span><br/> <span style="color: #993300;">#define SMS_GND 6</span></p>
<p><span style="color: #993300;">int soilMoist; // analogical value obtained from sensor</span></p>
<p><span style="color: #993300;">void setup ()</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> Serial.begin(9600);</span><br/> <span style="color: #993300;"> pinMode(SMS_VCC,OUTPUT);</span><br/> <span style="color: #993300;"> pinMode(SMS_GND,OUTPUT);</span></p>
<p><span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop (void)</span> <br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> soilMoist = getSoilMoisture();</span> <br/> <span style="color: #993300;"> Serial.print("Soil Moisture: ")</span><br/> <span style="color: #993300;"> Serial.print(soilMoist)</span><br/> <span style="color: #993300;"> Serial.println(" %")</span><br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">/***************************************************</span><br/> <span style="color: #993300;">* Capture soil Moisture data</span><br/> <span style="color: #993300;">****************************************************/</span><br/> <span style="color: #993300;">int getSoilMoisture()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> int anaValue;</span></p>
<p><span style="color: #993300;"> digitalWrite(SMS_VCC,LOW); // drive a current through the divider in one direction</span><br/> <span style="color: #993300;"> digitalWrite(SMS_GND,HIGH);</span><br/> <span style="color: #993300;"> delay(1000); // wait a moment for capacitance effects to settle</span><br/> <span style="color: #993300;"> anaValue=analogRead(SOIL_MOIST_PIN);</span></p>
<p><span style="color: #993300;"> digitalWrite(SMS_VCC,HIGH); // reverse the current</span><br/> <span style="color: #993300;"> digitalWrite(SMS_GND,LOW);</span><br/> <span style="color: #993300;"> delay(1000); // give as much time in 'reverse' as in 'forward'</span><br/> <span style="color: #993300;"> digitalWrite(SMS_VCC,LOW); // stop the current</span></p>
<p><span style="color: #993300;"> anaValue = map(anaValue, 1023, 0, 0, 100);</span><br/> <span style="color: #993300;"> return anaValue;</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p>Nos testes preliminares para o desenvolvimento do SW, usaremos um potenciômetro de 10K ohms entre + 5V e GND, simulando a saída analógica do sensor de umidade. Por agora isso será suficiente, uma vez que iremos discutir este sensor mais profundamente no capítulo 1.5.<br/> Agora que todas as rotinas para os sensores estão prontas e testadas individualmente, criaremos uma função específica onde todos os sensores serão lidos ao mesmo tempo:</p>
<br/>
<p><span style="color: #993300;">void readSensors(void)</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> tempDHT = dht.readTemperature(); //Read temperature and humidity values from DHT sensor:</span><br/> <span style="color: #993300;"> humDHT = dht.readHumidity();</span><br/> <span style="color: #993300;"> lumen = getLumen(LDR_PIN);</span><br/> <span style="color: #993300;"> soilMoist = getSoilMoist();</span><br/> <span style="color: #993300;">}</span></p>
<pre><br/><br/>
</pre>
<p>Procure fazer alguns testes com os sensores, como cobrir o LDR com um pano ou a mão, colocar o dedo diretamente no DHT, etc. , e veja o range de variação dos dados Use o Serial Monitor como saída para leitura dos dados.</p>
<p></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/08/sensors-output-serial.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/sensors-output-serial.png?w=840&width=703" width="703" class="align-full"/></a></p>
<p class="p1"><span class="s1">Abaixo o código completo:</span></p>
</div>
<div id="rich-embed-files" class="ible-files"></div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FYJ/KTDQ/ISCAWLCU/FYJKTDQISCAWLCU.ino"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="Sensors_Setup_and_Test.ino"/><span class="title">Sensors_Setup_and_Test.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 class="p1"><span class="s1">1.3: Adicionando um Display LCD para monitoramento local</span></h2>
<div id="photoset-SE167W1IRXTHBO3" class="photoset"></div>
<div class="step-body"><div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/09/02/ardufarmbot-controlando-um-tomateiro-com-a-ajuda-de-um-arduino-e-internet-das-coisas-iot/ardufarmbot_sensors_display_diagram/"><img src="https://mjrobot.files.wordpress.com/2016/08/ardufarmbot_sensors_display_diagram.png?w=382&h=337&crop=1" width="382" height="337" title="ArduFarmBot_Sensors_Display_Diagram" alt="ArduFarmBot_Sensors_Display_Diagram"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/09/02/ardufarmbot-controlando-um-tomateiro-com-a-ajuda-de-um-arduino-e-internet-das-coisas-iot/img_4705/"><img src="https://mjrobot.files.wordpress.com/2016/08/img_4705.jpg?w=450&h=337&crop=1" width="450" height="337" title="IMG_4705" alt="IMG_4705"/></a></div>
</div>
</div>
</div>
<p class="p1"><span class="s1">É claro que nem sempre será possível usar o monitor serial para analisar a leitura de nossos sensores. Assim, para monitorização local, será adicionado um LCD ao projecto. A escolha ficou com um módulo LCD de 4 linhas de 20 caracteres cada, que permite configuração de contraste através de um potenciômetro instalado em sua parte traseira e comunicação I2C.</span></p>
<p class="p1"><span class="s1"><img class=" wp-image-6026 alignleft" src="https://mjrobot.files.wordpress.com/2016/08/fzxwqolirxthf88-small.jpg?w=200&h=268" alt="fzxwqolirxthf88-small" width="200" height="268"/>Para comunicação serial do tipo I2C com o Arduino, o LCD possui 4 pinos:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">GND</span></li>
<li class="li1"><span class="s1">VCC</span></li>
<li class="li1"><span class="s1">SDA</span></li>
<li class="li1"><span class="s1">SCL</span></li>
</ul>
<p class="p1"><span class="s1">O pino SDA será ligado em nosso caso a entrada A4 do Arduino e o pino SCL ao A5, como mostrado no diagrama acima.</span></p>
<p class="p1"><span class="s1">Uma vez que os 4 fios são conectados, a próxima coisa a fazer é baixar e instalar a biblioteca I2C para o seu display LCD, a qual pode ser usada tanto para um display do tipo 20 x 4 quanto para o 16 x 2 (2 linhas de 16 caracteres):</span></p>
<p class="p3"><span class="s1"><a href="https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library">https://github.com/fdebrabander/Arduino-LiquidCrys…</a></span></p>
<p class="p1"><span class="s1">Execute em seu Arduino o programa exemplo “Hello World” que vem incluído com a biblioteca, mudando o set-up padrão (16 × 2) para o nosso 20 x 4. O endereço default “0x27” funcionou bem em meu caso:</span></p>
<p>#include <Wire.h> <br/> #include <LiquidCrystal_I2C.h></p>
<p>// Set the LCD address to 0x27 for a 20 chars and 4 line display<br/> LiquidCrystal_I2C lcd(0x27, 20, 4);</p>
<p><span style="color: #993300;">void setup()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> // initialize the LCD</span><br/> <span style="color: #993300;"> lcd.begin();</span></p>
<p><span style="color: #993300;"> // Turn on the blacklight and print a message.</span><br/> <span style="color: #993300;"> lcd.backlight();</span><br/> <span style="color: #993300;"> lcd.print("Hello, world!");</span><br/> <span style="color: #993300;">}</span></p>
<p><span style="color: #993300;">void loop()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> // Do nothing here...</span><br/> <span style="color: #993300;">}</span></p>
<pre><br/><br/>
</pre>
<p>Nota: Se você não tem certeza sobre o seu endereço I2C de seu LCD, uma simples varredura em seu HW irá mostrar se existem dispositivos I2C conectados, se estão funcionando corretamente e em qual seu endereço. O código para fazer o scanner pode ser encontrado aqui:<a href="http://playground.arduino.cc/Main/I2cScanner">http://playground.arduino.cc/Main/I2cScanner</a></p>
<p><img class="lazy-img alignnone" src="https://cdn.instructables.com/FQR/FX7O/IRXTHFGW/FQRFX7OIRXTHFGW.SMALL.jpg" alt="57ba02f2deafa4839d00151e.jpeg" width="375" height="281"/></p>
<p class="p1"><span class="s1">Como exemplo, em meu caso ao executar o programa obtive no </span>Monitor Serial :</p>
<p><span><em> Scanning..</em></span></p>
<p><span><em> I2C device found at address 0x27 !</em></span></p>
<p><span><em> done</em></span></p>
<p class="p1"><span class="s1">Vamos incorporar as funções, definições específicas, etc. referentes ao display em nosso último código, para que possamos assim ver as leituras de sensores em LCD:</span></p>
</div>
<div id="rich-embed-files" class="ible-files"></div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/F94/DYQA/ISCAWML3/F94DYQAISCAWML3.ino"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="Sensors_Setup_and_Test_LCD.ino"/><span class="title">Sensors_Setup_and_Test_LCD.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 class="p1"><span class="s1">1.4: Atuadores e botões para controle local</span></h2>
<p class="p2"><span class="s1"><span>Atuadores</span></span></p>
<p class="p3"><span class="s1">Até agora, pudemos obter os dados gerados pelos sensores e exibi-los no monitor serial e no LCD. É hora de fazer alguma coisa com esses dados. Vamos pensar sobre os atuadores!</span></p>
<p class="p3"><span class="s1">Como discutido na introdução, nosso objetivo final aqui é cuidar de uma plantação de tomate. Com os dados fornecidos por sensores, saberemos a temperatura e umidade do ar, a luminosidade e o mais importante quão “seco” se encontra o solo onde está a plantação. Com esses dados em mãos, o nosso programa deverá decidir se seria necessário irrigar a plantação, ligando uma bomba elétrica para bombear água ou uma lâmpada elétrica para fornecer o calor necessário para a cultura. Para isso, usaremos pequenos Módulos de %V para relés para a ativação da bomba e lâmpada. O diagrama do Módulo de Relé pode ser visto abaixo.</span></p>
<div class="step-body"><p><a href="https://cdn.instructables.com/FUL/LOOL/IRXTV5RI/FULLOOLIRXTV5RI.MEDIUM.jpg" target="_blank"><img src="https://cdn.instructables.com/FUL/LOOL/IRXTV5RI/FULLOOLIRXTV5RI.MEDIUM.jpg?width=703" width="703" class="align-full"/></a></p>
<p class="p1">Módulos de relés podem apresentar várias nomenclaturas para seus pinos de entrada, tais como: “G”, “V”, “S” ou “S”, “-“, “+” ou “In”, “Vcc”, ” GND “, etc.</p>
<p class="p1"><span class="s1">Olhando para o diagrama, dependendo do seu módulo de relé, é necessário conectar:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">Arduino 5V ==> “V” ou “+” ou “Vcc”</span></li>
<li class="li1"><span class="s1">Arduino GND ==> “G” ou “-” ou “GND”</span></li>
<li class="li1"><span class="s1">Arduino OUT ==> “S” ou “In” (em nosso caso o “Arduino OUT” deve ser D10 para Bomba e D8 para Lamp)</span></li>
</ul>
<p class="p1"><span class="s1">Normalmente você vai encontrará como saída, 3 pinos: “NA” (ou NO), “Ref”, e “NF ” (ou NC), que são:” Normal Open ou Aberto”, Referência e” Normal Closed ou Fechado “. Nós usaremos o par: NA e Ref (centro). No diagrama acima, “NA” é o terminal para conectar-se ao positivo da fonte de alimentação (12 ou 9VDC para Bomba e 127 ou 220VAC para a lâmpada, conforme seu caso). O “Ref” será conectado à bomba ou da lâmpada, como mostrado na figura acima. Para saber mais sobre relés, visite: “<a href="https://arduino-info.wikispaces.com/ArduinoPower"><span class="s2"> Controlling Power with Arduino</span></a> “.</span></p>
<p class="p1"><span class="s1">Juntamente com os relés, opcionalmente 2 LEDs podem ser utilizados para mostrar se os relés estão ligados ou desligados:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">LED vermelho: Bomba</span></li>
<li class="li1"><span class="s1">LED verde: Lâmpada</span></li>
</ul>
<p class="p1"><span class="s1">Para o teste é ótimo se ter os LEDs instalados em seu BreadBord, mas para o projeto final você pode eliminar-los, reduzindo a carga na saída do pino do Arduino (mesmo porque os módulos de relés em geral possuem um pequeno LED vermelho incorporado). Trabalhando juntos, eles “puxarão” uma quantidade razoável de corrente do Arduino (você poderá perceber uma redução no brilho no LCD). Outra alternativa é utilizar saídas digitais diferentes para os LEDs e relés, o que claro reduz a disponibilidade de pinos para outros usos. </span></p>
<div><h4> <a href="https://cdn.instructables.com/FGJ/DSXT/IRXTK2JA/FGJDSXTIRXTK2JA.MEDIUM.jpg" target="_blank"><img src="https://cdn.instructables.com/FGJ/DSXT/IRXTK2JA/FGJDSXTIRXTK2JA.MEDIUM.jpg?width=703" width="703" class="align-full"/></a></h4>
<p class="p1"><span class="s1"><span>Botões</span></span></p>
<p class="p2"><span class="s1">Com base nas leituras dos sensores, um operador poderia decidir controlar manualmente a bomba e / ou lâmpada. Para isso, dois botões do tipo “push-button” serão incorporados ao projeto. Eles vão trabalhar em um modo de “alternância” (“Toggle”): Se um atuador está “ON”, pressionando-se o botão, ele passa a “OFF” e vice-versa. A lógica do botão será “normalmente fechada”, o que significa que a entrada do Arduino estará constantemente em “HIGH” (será usado um resistor de pull-up interno do Arduino). Pressionando-se o botão, uma estado “LOW” será aplicada ao pino do Arduino.</span></p>
<p class="p2"><span class="s1">Da mesma maneira que fizemos com os sensores, a toda vez que executemos o <span><i>loop ()</i></span> , uma função <span><i>readLocalCmd ()</i></span> será executada. Esta função lerá o estado dos botões, atualizando o status de variáveis correspondentes aos atuadores (<span><i>pumpSatus</i></span> e <span><i>lampStatus</i></span>). Note que a função <em><span>debounce</span></em><span><i>(pin)</i></span> é chamado ao invés de um <span><em>digitalRead (PIN)</em>.</span> Isso é para evitar falsas leituras do botão. Se você quiser saber mais sobre debouncing, consulte: </span><span> </span><a href="https://www.arduino.cc/en/Tutorial/Debounce">Debouncing Tutorial</a><span>.</span></p>
</div>
<p><span style="color: #993300;">/****************************************************************</span><br/> <span style="color: #993300;">* Read local commands (Pump and Lamp buttons are normally "HIGH"):</span><br/> <span style="color: #993300;">****************************************************************/</span><br/> <span style="color: #993300;">void readLocalCmd()</span> <br/> <span style="color: #993300;">{</span> <br/> <span style="color: #993300;"> int digiValue = debounce(PUMP_ON);</span><br/> <span style="color: #993300;"> if (!digiValue)</span> <br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> pumpStatus = !pumpStatus;</span><br/> <span style="color: #993300;"> showDataLCD();</span><br/> <span style="color: #993300;"> aplyCmd();</span><br/> <span style="color: #993300;"> }</span></p>
<p><span style="color: #993300;"> digiValue = debounce(LAMP_ON);</span><br/> <span style="color: #993300;"> if (!digiValue)</span> <br/> <font color="#993300"> {</font><br/> <span style="color: #993300;"> lampStatus = !lampStatus;</span><br/> <span style="color: #993300;"> showDataLCD();</span><br/> <span style="color: #993300;"> aplyCmd();</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;">}</span></p>
<pre><br/><br/>
</pre>
<p>No caso em que um botão é pressionado, uma outra função será chamada:aplyCmd () . E como o nome diz, ela aplicará o comando correspondente, ligando ou desligando os atuadores:</p>
<p><span style="color: #993300;">/***************************************************</span><br/> <span style="color: #993300;">* Receive Commands and act on actuators</span><br/> <span style="color: #993300;">****************************************************/</span><br/> <span style="color: #993300;">void aplyCmd()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> if (pumpStatus == 1) digitalWrite(PUMP_PIN, HIGH);</span><br/> <span style="color: #993300;"> if (pumpStatus == 0) digitalWrite(PUMP_PIN, LOW);</span></p>
<p><span style="color: #993300;"> if (lampStatus == 1) digitalWrite(LAMP_PIN, HIGH);</span><br/> <span style="color: #993300;"> if (lampStatus == 0) digitalWrite(LAMP_PIN, LOW);</span><br/> <span style="color: #993300;">}</span></p>
<pre><span style="color: #993300;"><br/><br/>
</span></pre>
<p><span class="font-size-3">Considerações sobre o “Timming” do programa</span></p>
<pre><span style="color: #993300;"> </span></pre>
<div><p class="p2"><span class="s1">Quando pensamos sobre as tarefas a serem executadas, podemos agrupar-las em: </span></p>
<ol class="ol1">
<li class="li2"><span class="s1">Ler sensores</span></li>
<li class="li2"><span class="s1">ler botões (comando local)</span></li>
<li class="li2"><span class="s1">Atuar sobre Bomba / Lâmpada</span></li>
<li class="li2"><span class="s1">Exibir todos os dados</span></li>
</ol>
<p class="p2"><span class="s1">Percebemos que o “timming” de quando deveríamos realizar tais tarefas não são necessariamente os mesmos. Por exemplo, para ler os dados de temperatura e de umidade do DHT 22, temos de esperar pelo menos 2 segundos entre medidas, mas diferenças em minutos não farão grandes diferenças. Para o sensor de umidade do solo, quanto menos medições fizermos, melhor (evita corrosão das pontas de prova devido a electrolise) e por último mas não menos importante, a luz do dia não vai variar instantaneamente. Mas quando pensamos sobre os atuadores, logo que se pressione um botão, gostaríamos (e possivelmente precisaríamos) de uma reacção rápida.</span></p>
<p class="p2"><span class="s1">Assim, a última instrução antes do final do <span><i>setup ()</i></span> será a inicialização de um temporizador principal usando a função” <span><i>millis ()</i></span> ” em vez de espalhar um monte de <em><span>delays()’</span></em>s pelo código:</span></p>
<p class="p2"><span class="s1" style="color: #993300;"><i>startTiming = millis (); // Iniciar o “relógio do programa”</i></span></p>
<p class="p2"><span class="s1">Durante o <em><span>loop()</span></em>, a primeira instrução será a de incrementar a variável<span><i>startTiming</i></span> com uma temporização real.</span></p>
<p class="p2"><span class="s1" style="color: #993300;"><i>elapsedTime = millis () – startTiming</i> ;</span></p>
<p class="p2"><span class="s1">Depois disso, leremos o estado dos botões usando a função <span><i>readLocalCmd (</i></span><i>).</i> Esta leitura irá acontecer toda a vez que o programa execute o <em><span>loop ()</span></em>.</span></p>
<p class="p2"><span class="s1" style="color: #993300;"><i>readLocalCmd (); // Ler estado dos botões locais</i></span></p>
<p class="p2"><span class="s1">Em relação aos sensores, fazemos a leitura a cada 5 segundos, por exemplo, e não em cada loop:</span></p>
<h4><span style="color: #993300;"><em>IF (ELAPSEDTIME > (5000))</em></span></h4>
</div>
<p><span style="color: #993300;"><em>{</em></span></p>
<p><span style="color: #993300;"><em> readSensors();</em></span></p>
<p><span style="color: #993300;"><em> printData();</em></span></p>
<p><span style="color: #993300;"><em> startTiming = millis();</em></span></p>
<p><span style="color: #993300;"><em>}</em></span></p>
<p class="p1"><span class="s1">Abaixo o código completo para testar a nossa “Estação local”:</span></p>
</div>
<div id="rich-embed-files" class="ible-files"></div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FIR/E3NY/ISCAWNNQ/FIRE3NYISCAWNNQ.ino"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="local_Station.ino"/><span class="title">local_Station.ino</span></a></li>
</ul>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 class="p1"><span class="s1">1.5: Aprofundando com o sensor de humidade do solo</span></h2>
<p class="p2"><span class="s1">Você poderá pular esta etapa se quiser, mas acho que seria interessante aprofundar-nos um pouco mais no estudo deste simples, mas crítico componente para o projeto. Como brevemente explicado anteriormente, o “Soil Moisture Sensor”, ou higrômetro, é um simples “divisor de tensão resistivo”.</span></p>
<p class="p2"><span class="s1">Sabendo disso, podemos construir um sensor muito simples usando duas sondas metálicas como pregos galvanizados, pinos ou parafusos. Abaixo você poderá ver o que criei utilizando-se de materiais simples: dois parafusos ligados a dois fios (preto / vermelho). Depois em um segundo sensor, foram adicionados um terceiro fio e um resistor.</span></p>
<div class="step-body"><p><a href="https://cdn.instructables.com/FVB/ORFF/IRXTYQOI/FVBORFFIRXTYQOI.MEDIUM.jpg" target="_blank"><img src="https://cdn.instructables.com/FVB/ORFF/IRXTYQOI/FVBORFFIRXTYQOI.MEDIUM.jpg?width=703" width="703" class="align-full"/></a></p>
<p class="p1"><span class="s1">Conforme descrito no item 1.2, “R1” é a “resistência do solo” (não é o melhor termo científico, mas está OK). Utilizando-se de 3 amostras de solo em diferentes estados de umidade, podemos medir o valor esse valor R1 utilisando-se de um multímetro comum e corrente, como mostrado na foto abaixo:</span></p>
<p class="p1"><a href="https://mjrobot.files.wordpress.com/2016/08/sms-setup.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/sms-setup.png?w=840&width=703" width="703" class="align-full"/></a></p>
<ul>
<li><span class="s2">Seco: R1 = >20 Kohm (aprox)</span></li>
<li><span class="s2">Húmido: R1 = 4K para 6Kohm (aprox.) </span></li>
<li><span class="s2">Molhado: R1 = >1kohm (aprox)</span><p class="p1"><span class="s2">R2 é a resistência física usada para completar o Divisor de Tensão (Vamos começar com um potenciômetro 10K para set-up). Calculando o Vin na porta A1 do Arduino , proporcionalmente à VCC, chegaríamos a equação:</span></p>
<p class="p1"><span class="s2">Vin = R2 / (R1 + R2) * VCC ou Vin / VCC = 10K / (R1 + 10K) * 100 [%]</span></p>
<p class="p1"><span class="s2">Usando os valores reais medidos com o multímetro, podemos antecipar que os resultados devem ser:</span></p>
</li>
</ul>
<ul>
<li><p class="p1">Seco: 10K / 30K *100 ==> <30%</p>
</li>
<li><span class="s2">Húmido: 10K / 15K * 100 ==> ~ 67%</span></li>
<li><span class="s2">Molhado: 10K / 11K * 100 ==> > 90%</span></li>
</ul>
<p><a href="https://mjrobot.files.wordpress.com/2016/08/sms-measuriments.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/sms-measuriments.png?w=840&width=703" width="703" class="align-full"/></a></p>
<p class="p1"><span class="s1">Fazendo as conexões com o Arduino e executando o código desenvolvido até agora, teremos como resultado:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">Seco: 13%</span></li>
<li class="li1"><span class="s1">Húmido: 62%</span></li>
<li class="li1"><span class="s1">Molhado: 85%</span></li>
</ul>
<p class="p1"><span class="s1">Obviamente devido a que mudei a posição dos sensores na terra R1 mudará um pouco, além de que o VCC também não é exatamente 5V, os valores práticos são um pouco diversos do teórico. Mas como o que realmente importa é o intervalo de variação e não o valor absoluto, o resultado foi muito satisfatório.</span></p>
<p class="p1"><span class="s1">O sensor será utilizado em 3 estados distintos:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">Molhado (Wet): Mais de 60% (não ligaremos a bomba de maneira nenhuma)</span></li>
<li class="li1"><span class="s1">Húmido: Entre 40 e 60% (Onde queremos trabalhar) e</span></li>
<li class="li1"><span class="s1">Seco: Abaixo de 30% (precisaremos ligar a bomba para aumentar a umidade)</span></li>
</ul>
<p class="p1"><span class="s1">Como você pode observar, utilizando-se R2 como 10K ohm funcionou bem, o que nos leva a substituir o potenciômetro por um resistor fixo em nosso “Soil Moisture Sensor”.</span></p>
<p class="p1"><span class="s1">Outra coisa que se percebe quando testamos os sensores, é que ao fazer as medições vai se acumulando um pequeno erro nas leituras. Isto porque o sensor também se comportará como um “capacitor”. Ao se “energizar” o sensor para uma única captura de dados precisamos esperar um tempo razoável, mesmo depois de cortar o fornecimento de energia para que o mesmo possa se “descarregar “. Revertendo a corrente ajudará, mas não é suficiente.</span></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/08/soilmoisture-sensor-readings-comp.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/soilmoisture-sensor-readings-comp.png?w=840&width=703" width="703" class="align-full"/></a></p>
<p class="p1"><span class="s1">Os gráficos acima mostram 2 conjuntos de medições:</span></p>
<ol class="ol1">
<li class="li1"><span class="s1"><span>Linha azul</span> : Um ciclo de 10 medições a cada 1 segundo entre amostras e com 1 minuto entre os ciclos</span></li>
<li class="li1"><span class="s1"><span>Linha Laranja</span> : Um ciclo de 10 medições a cada 1 segundo entre amostras e com 5 minutos entre ciclos</span></li>
</ol>
<p class="p1"><span class="s1">Com intervalos de 1 segundo, cada nova amostra será aumentado significativamente. Esperar 1 minuto após desligar a energia irá diminuir o “efeito de tensão de armazenamento”, mas não vai eliminá-la por completo sendo que um valor residual será adicionado à próxima medição. O aumento do intervalo de ciclos para 5 minutos, por exemplo, praticamente eliminará o erro.</span></p>
<p class="p1"><span class="s1">Com base nos resultados acima, o código final não deve tomar amostras com uma frequência de menos do que 10 min.</span></p>
<p class="p1"><span class="s1">O vídeo abaixo, mostra os testes efetuados com o sensor:</span></p>
<div class="jetpack-video-wrapper"><a href="https://youtu.be/bLhwOoBBWZ8">https://youtu.be/bLhwOoBBWZ8</a></div>
<div class="jetpack-video-wrapper"></div>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 class="p1"><span class="s1">1.6: Compatibilizando as operações automática e manual </span></h2>
<div id="photoset-SD8W859IRXTZ6OM" class="photoset"><div class="photoset-row cols-1"></div>
<div class="photoset-row cols-2"><div class="photoset-cell image-cell"></div>
<div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a href="http://www.instructables.com/file/FD7XJ4ZIRXTZO2D/" target="_blank"><img src="https://cdn.instructables.com/FD7/XJ4Z/IRXTZO2D/FD7XJ4ZIRXTZO2D.MEDIUM.jpg?width=703" width="703" class="align-full"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p class="p1"><span class="s1">Como pudemos ver na última etapa, precisaremos esperar tempos maiores entre as medições do sensor de umidade, por exemplo: 10minutos. Isto está Ok para as nossas necessidades automáticas, mas para a operação manual não vamos querer “esperar” dezenas de minutos olhando para o ArduFarmBot para saber se um valor medido pelo sensor mudou. Para solucionar o problema, introduziremos um terceiro botão de controle em nosso projeto, o qual será usado para exibir os dados reais e instantâneos dos sensores a qualquer momento, independente das programações de leituras automáticas.</span></p>
<p><a href="https://cdn.instructables.com/FG0/H1QM/IRXTZ7O9/FG0H1QMIRXTZ7O9.MEDIUM.jpg" target="_blank"><img src="https://cdn.instructables.com/FG0/H1QM/IRXTZ7O9/FG0H1QMIRXTZ7O9.MEDIUM.jpg?width=703" width="703" class="align-full"/></a></p>
<p class="p1"><span class="s1">Para o Push-Button, usaremos o pino digital D17 (o mesmo que está compartilhado com a entrada analógica A3). Introduziremos também um “LED de aviso” (o amarelo na foto) conectada ao pino 13. Este LED acenderá toda a vez em que os sensores estão sendo atualizados. Abaixo a nova função <span><em>readLocalCmd()</em></span> :</span></p>
<p><span style="color: #993300;">/****************************************************************</span><br/> <span style="color: #993300;">* Read local commands (Pump and Lamp buttons are normally "HIGH"):</span><br/> <span style="color: #993300;">****************************************************************/</span><br/> <span style="color: #993300;">void readLocalCmd()</span> <br/> <span style="color: #993300;">{</span> <br/> <span style="color: #993300;"> int digiValue = debounce(PUMP_ON);</span><br/> <span style="color: #993300;"> if (!digiValue)</span> <br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> pumpStatus = !pumpStatus;</span><br/> <span style="color: #993300;"> showDataLCD();</span><br/> <span style="color: #993300;"> aplyCmd();</span><br/> <span style="color: #993300;"> }</span></p>
<p><span style="color: #993300;"> digiValue = debounce(LAMP_ON);</span><br/> <span style="color: #993300;"> if (!digiValue)</span> <br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> lampStatus = !lampStatus;</span><br/> <span style="color: #993300;"> showDataLCD();</span><br/> <span style="color: #993300;"> aplyCmd();</span><br/> <span style="color: #993300;"> }</span></p>
<p><span style="color: #993300;"> digiValue = debounce(SENSORS_READ);</span><br/> <span style="color: #993300;"> if (!digiValue)</span> <br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> digitalWrite(YELLOW_LED, HIGH);</span> <br/> <span style="color: #993300;"> lcd.setCursor (0,0);</span><br/> <span style="color: #993300;"> lcd.print("< Updating Sensors >");</span><br/> <span style="color: #993300;"> readSensors();</span><br/> <span style="color: #993300;"> digitalWrite(YELLOW_LED, LOW);</span> <br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p>Outro ponto a considerar, é a introdução de um segundo “Soil Moisture Sensor” (higrômetro). Em nosso projeto final utilizaremos 2 sensores em pontos diferentes da plantação. Nós usaremos a média das leitura para decidir quando se deve ligar a bomba, por exemplo.</p>
<p><br/> O “VCC e GND” dos sensores serão o mesmo (D7 e D6 respectivamente) e usaremos a entrada A2 do Arduino para o segundo sensor. Se a area da plantação é pequena não justificando 2 sensores, somente o valor lido em A1 será considerado pelo SW. (Isto deve ser informado na variável correspondente na area de set-up do SW).</p>
<p class="p1"><span style="color: #993300;">// to be used by SM Sensor</span><br/> <span style="color: #993300;">int soilMoist;</span><br/> <span style="color: #993300;">int soilMoistAlert = 0;</span><br/> <span style="color: #993300;">int DRY_SOIL = 30;</span><br/> <span style="color: #993300;">int WET_SOIL = 60;</span><br/> <span style="color: #993300;">int numSM = 1; // “numSM” defines number of moisture sensors that are connected</span><br/> <span style="color: #993300;">int numSamplesSMS = 1; // “numSamplesSMS” defines number of samples of each reading cycle</span></p>
<p class="p1"></p>
<p class="p1"><span class="s1">O número de amostras de cada ciclo também será definido por uma variável específica: “numSamplesSMS”. Em princípio apenas uma leitura é suficiente, levando-se em consideração que as leituras que fazemos em um curto espaço de tempo introduzirão erros devido ao efeito de capacitância. Se você começar a ver erros na leitura, talvez sejam necessárias tomar amostras extras.</span></p>
<p class="p1"></p>
<p class="p1"><span class="s1">Abaixo a nova função para o “Soil Moisture Sensor”:</span></p>
<p><span style="color: #993300;">/***************************************************</span><br/> <span style="color: #993300;">* Capture soil Moisture data</span><br/> <span style="color: #993300;">****************************************************/</span><br/> <span style="color: #993300;">int getSoilMoist()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> int i = 0;</span><br/> <span style="color: #993300;"> int anaValue1 = 0;</span><br/> <span style="color: #993300;"> int anaValue2 = 0;</span><br/> <span style="color: #993300;"> for(i = 0; i < numSamplesSMS; i++) // // "numSamplesSMS" defines number of samples of each reading cycle</span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> digitalWrite(SMS_VCC,LOW); // drive a current through the divider in one direction</span><br/> <span style="color: #993300;"> digitalWrite(SMS_GND,HIGH);</span><br/> <span style="color: #993300;"> delay(500); // wait a moment for capacitance effects to settle</span><br/> <span style="color: #993300;"> anaValue1 += analogRead(SOIL_MOIST_1_PIN);</span><br/> <span style="color: #993300;"> delay(500); // wait a moment for ADC settle-up</span><br/> <span style="color: #993300;"> anaValue2 += analogRead(SOIL_MOIST_2_PIN);</span></p>
<p><span style="color: #993300;"> digitalWrite(SMS_VCC,HIGH); // reverse the current</span><br/> <span style="color: #993300;"> digitalWrite(SMS_GND,LOW);</span><br/> <span style="color: #993300;"> delay(1000); // give as much time in 'reverse' as in 'forward'</span><br/> <span style="color: #993300;"> digitalWrite(SMS_VCC,LOW); // stop the current</span><br/> <span style="color: #993300;"> //delay (3000);</span><br/> <span style="color: #993300;"> }</span></p>
<p><span style="color: #993300;"> anaValue1 = anaValue1/(i);</span><br/> <span style="color: #993300;"> anaValue2 = anaValue2/(i);</span><br/> <span style="color: #993300;"> if (numSM == 2) anaValue1 = (anaValue1+anaValue2)/2; // "numSM" variable, defines number of moisture sensors that are connected</span></p>
<p><span style="color: #993300;"> anaValue1 = map(anaValue1, 1015, 3, 0, 100); //1015:0 (en el air) ==> 003:100% (poniendo un "short circuit)</span> <br/> <span style="color: #993300;"> Serial.println(anaValue1);</span><br/> <span style="color: #993300;"> return anaValue1;</span><br/> <span style="color: #993300;">}</span></p>
<p>O diagrama abaixo mostra as conexões completas para a estação local de controle</p>
<p><a href="https://cdn.instructables.com/FD4/39FQ/IRXTZKJU/FD439FQIRXTZKJU.MEDIUM.jpg" target="_blank"><img src="https://cdn.instructables.com/FD4/39FQ/IRXTZKJU/FD439FQIRXTZKJU.MEDIUM.jpg?width=703" width="703" class="align-full"/></a></p>
<div class="step-container"><div class="step-body"><h2>1.7: It’s show time!</h2>
</div>
</div>
<div class="step-container"><div class="step-body"><p><a href="https://cdn.instructables.com/FNI/NZS2/ISCB4EPY/FNINZS2ISCB4EPY.MEDIUM.jpg" target="_blank"><img src="https://cdn.instructables.com/FNI/NZS2/ISCB4EPY/FNINZS2ISCB4EPY.MEDIUM.jpg?width=703" width="703" class="align-center"/></a></p>
<p class="p1"><span class="s1">Neste ponto, já temos todo o HW no lugar e quase todos os elementos de SW desenvolvidos. O que falta agora é a “inteligência”, que permitirá ao nosso sistema realmente executar a tarefa de irrigar a plantação automaticamente! Para isto, precisaremos adicionar alguns “neurônios” ao nosso cérebro!</span></p>
<p class="p1"><span class="s1">Como discutido anteriormente, definiremos o intervalo inicial onde os sensores irão trabalhar. Esses valores deverão ser alterados mais tarde a partir de resultados de testes reias na plantação:</span></p>
<p class="p1"><span class="s1">Umidade do solo:</span></p>
<ul>
<li class="p1"><span class="s1">Molhado (Wet): Mais de 60% (não ligaremos a bomba de maneira nenhuma)</span></li>
<li class="p1"><span class="s1">Húmido: Entre 40 e 60% (Onde queremos trabalhar) e</span></li>
<li class="p1"><span class="s1">Seco: Abaixo de 30% (precisaremos ligar a bomba para aumentar a umidade)</span></li>
</ul>
<p class="p1"><span class="s1">Temperatura:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">Frio: Abaixo de 15oC (Ligar Luz / Calor *)</span></li>
<li class="li1"><span class="s1">Confortável: entre 20 oC e 25 oC</span></li>
<li class="li1"><span class="s1">Calor: Mais que 25 ° C (não vire-a luz / calor)</span></li>
</ul>
<p class="p1"><span class="s1">Leve:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">Escuro (noite): Abaixo de 40% (não ligar bomba)</span></li>
<li class="li1"><span class="s1">Luz (dia): Mais de 40%</span></li>
</ul>
<p class="p1"><span class="s1">(*) Você poderá opcionalmente testar aqui as novas <a href="https://www.amazon.com/gp/product/B01CH75SGY/ref=ox_sc_act_title_3?ie=UTF8&psc=1&smid=APJ320DT59KIZ"><span class="s2">luzes LED para vegetais hidropônicos</span></a> . Estas lâmpadas de LED podem ser utilizadas tanto para ajudar o crescimento mais rápido devido a luzes de frequências especiais como também para fornecer calor em caso de baixa temperatura.</span></p>
<p class="p1"><span class="s1">Você deverá ter em mente que cada tipo de semente possui uma faixa ideal de temperatura na qual ela crescerá mais rápidamente. Por exemplo, para os Tomates o tempo mínimo para as sementes germinarem será de 6 dias em temperaturas entre 20 e 25 oC, aumentando para temperaturas superiores ou inferiores a esta faixa:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">Temperatura: graus (oC): 10 15 20 25 30 35</span></li>
<li class="li1"><span class="s1">Tempo para germinação (dias): 43 14 8 6 6 9</span></li>
</ul>
<p class="p1"><span class="s1">Você pode verificar mais informações sobre esta relação (temp / dias de germinação) aqui: <a href="http://tomclothier.hort.net/page11.html"><span class="s2">O efeito da temperatura do solo na germinação de sementes</span></a></span></p>
<p class="p1"><span class="s1">Tendo em mãos estas 4 leitura (temperatura, umidade, Soil Moisture and luz), podemos criar uma matriz que definirá como queremos que os nossos tomates crescem:</span></p>
<p class="p1"><span class="s1">Então, tomemos nossas variáveis e definamos algumas novas valores:</span></p>
<p class="p1"><span class="s1">Para ser utilizado pelo sensor DHT:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">int tempDHT;</span></li>
<li class="li1"><span class="s1">int HOT_TEMP = 25;</span></li>
<li class="li1"><span class="s1">int COLD_TEMP = 15;</span></li>
</ul>
<p class="p1"><span class="s1">Para ser usado por sensor LDR:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">lumen int;</span></li>
<li class="li1"><span class="s1">int DARK_LIGHT = 40;</span></li>
</ul>
<p class="p1"><span class="s1">Para ser usado pelo higrômetro:</span></p>
<ul class="ul1">
<li class="li1"><span class="s1">int soilMoist;</span></li>
<li class="li1"><span class="s1">int DRY_SOIL = 40;</span></li>
<li class="li1"><span class="s1">int WET_SOIL = 60;</span></li>
</ul>
<p class="p1"><span class="s1">Com base nas definições acima, pensemos sobre algumas premissas-chave:</span></p>
<ol class="ol1">
<li class="li1"><span class="s1">Se é durante o dia (lumen > DARK_LIGHT) e o solo está SECO (soilMoist < DRY_SOIL) ==> BOMBA = ON </span></li>
<li class="li1"><span class="s1">Se é durante a noite (lumen < DARK_LIGHT) e o solo está SECO (soilMoist < DRY_SOIL) ==> BOMBA = OFF </span>(Tomates não gostam de receber água durante a noite)</li>
<li class="li1"><span class="s1">Se estiver frio (tempDHT <COLD_TEMP) ==> LAMPADA = ON</span></li>
<li class="li1"><span class="s1">Se estiver frio (tempDHT <COLD_TEMP) e solo muito húmido (soilMoist > WET_SOIL) ==> LAMP = OFF (para proteger a raiz)</span></li>
</ol>
<p class="p1"><span class="s1">Nesta primeira parte do projeto, vamos mantê-lo simples e não exploraremos todas as combinações possíveis e o papel da humidade do ar na equação. Explorar uma combinação mais complexa de sensores na 3º parte deste projeto, quando aplicaremos o ArduFarmBot em uma plantação real.</span></p>
<p class="p1"><span class="s1">O Código :</span></p>
<p class="p1"><span class="s1">Criaremos uma nova função, que baseado na leitura dos sensores, lidará automaticamente com os atuadores (ligar / desligar a bomba e lâmpada):<i>AutoControlPlantation ().</i> Esta função mostrada abaixo, será chamada em cada ciclo de leituras dos sensores:</span></p>
<p><span style="color: #993300;">void loop() </span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> // Start timer for measurements</span><br/> <span style="color: #993300;"> elapsedTime = millis()-startTiming;</span></p>
<p><span style="color: #993300;"> readLocalCmd(); //Read local button status</span><br/> <span style="color: #993300;"> showDataLCD();</span></p>
<p><span style="color: #993300;"> if (elapsedTime > (sampleTimingSeconds*1000)) </span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> readSensors();</span><br/> <span style="color: #993300;"> autoControlPlantation();</span><br/> <span style="color: #993300;"> startTiming = millis();</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;">}</span></p>
<p>A função terá 2 tarefas principais:<br/> Controle de bomba<br/> Controle da lâmpada</p>
<p class="p1"><span class="s1">O segmento de controle da bomba utilizará uma nova variável: ”<i>soilMoistAlert</i><i> “.</i></span></p>
<p><span style="color: #993300;">//--------------------------------- PUMP ------//</span><br/> <span style="color: #993300;">if (soilMoist < DRY_SOIL && lumen > DARK_LIGHT) </span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> if (soilMoistAlert == HIGH)</span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> soilMoistAlert = LOW; </span><br/> <span style="color: #993300;"> turnPumpOn();</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> else soilMoistAlert = HIGH;</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> else soilMoistAlert = LOW;</span></p>
<p></p>
<p>Esta variável será utilizada para evitar um “falso verdadeiro”. Então por exemplo, se tivermos um verdadeiro no resultado do teste: soilMoist <DRY_SOIL e que não seja durante a noite (lumen> DARK_LIGHT), não ligaremos imediatamente na bomba, mas ao invés disso, esperaremos o próximo ciclo verificando se o ” solo está muito seco “. Se o resultado for um “sim” (obtendo um “verdadeiro” como resposta duas vezes), somente aí a função turnPumpOn() será chamada:</p>
<p><span style="color: #993300;">/***************************************************</span><br/> <span style="color: #993300;">* TurnPumOn </span><br/> <span style="color: #993300;">****************************************************/</span><br/> <span style="color: #993300;">void turnPumpOn()</span><br/> <span style="color: #993300;">{</span><br/> <span style="color: #993300;"> digitalWrite(PUMP_PIN, HIGH);</span><br/> <span style="color: #993300;"> pumpStatus = 1;</span><br/> <span style="color: #993300;"> showDataLCD();</span><br/> <span style="color: #993300;"> delay (timePumpOn*1000);</span><br/> <span style="color: #993300;"> digitalWrite(PUMP_PIN, LOW);</span><br/> <span style="color: #993300;"> pumpStatus = 0;</span><br/> <span style="color: #993300;"> showDataLCD();</span><br/> <span style="color: #993300;">} </span></p>
<p></p>
<p>A bomba deverá permanecer ligada por um determinado período de tempo, definido pela variável: ” timePumpOn” em segundos.<br/> Note que também mudaremos a função que exibe dados no LCD criando um 3o. estado:</p>
<br/>
<ul class="ul1">
<li class="li1"><span class="s1">“0”: Bomba OFF (pumpStatus = 0; e soilMoistAlert = 0;)</span></li>
<li class="li1"><span class="s1">“X”: Bomba em alerta (pumpStatus = 0; e soilMoistAlert = 1;)</span></li>
<li class="li1"><span class="s1">“1”: Bomba ON (pumpStatus = 1; e soilMoistAlert = 0;)</span></li>
</ul>
<pre> <br/></pre>
<p><span style="color: #993300;">lcd.print("Pump: ");</span><br/> <span style="color: #993300;">if (soilMoistAlert == 1) lcd.print ("X");</span><br/> <span style="color: #993300;"> else lcd.print(pumpStatus);</span></p>
<pre> </pre>
<p>O mesmo princípio será aplicado ao controle da lâmpada, onde uma “baixa temperatura” será o “trigger” para acionar a lâmpada desde que o solo não esteja muito molhado”.</p>
<p></p>
<p>Abaixo a função completa: autoControlPlantation ():</p>
<pre> <br/></pre>
<p><span style="color: #993300;">/***************************************************</span><br/> <span style="color: #993300;">* Automatically Control the Plantation based on sensors reading</span><br/> <span style="color: #993300;">****************************************************/</span><br/> <span style="color: #993300;">void autoControlPlantation()</span><br/> <span style="color: #993300;">{ </span><br/> <span style="color: #993300;"> //--------------------------------- PUMP ------//</span><br/> <span style="color: #993300;"> if (soilMoist < DRY_SOIL && lumen > DARK_LIGHT) </span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> if (soilMoistAlert == HIGH)</span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> soilMoistAlert = LOW; </span><br/> <span style="color: #993300;"> turnPumpOn();</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> else soilMoistAlert = HIGH;</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> else soilMoistAlert = LOW;</span></p>
<p><span style="color: #993300;"> //--------------------------------- HEAT ------//</span><br/> <span style="color: #993300;"> if (tempDHT < COLD_TEMP && soilMoist < WET_SOIL) </span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> if (tempLowAlert == HIGH)</span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> tempLowAlert = LOW; </span><br/> <span style="color: #993300;"> digitalWrite(LAMP_PIN, HIGH);</span><br/> <span style="color: #993300;"> lampStatus = 1;</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> else tempLowAlert = HIGH;</span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;"> else </span><br/> <span style="color: #993300;"> {</span><br/> <span style="color: #993300;"> tempLowAlert = LOW;</span><br/> <span style="color: #993300;"> digitalWrite(LAMP_PIN, LOW);</span><br/> <span style="color: #993300;"> lampStatus = 0; </span><br/> <span style="color: #993300;"> }</span><br/> <span style="color: #993300;">}</span></p>
<p></p>
<p>Neste ponto, o ArduFarmBot esta totalmente funcional em termos de HW e SW e já poderia ser instalado em uma plantação para testes.</p>
<div class="step-body"><p>O código completo pode ser encontrado abaixo:</p>
</div>
<ul id="attachments" class="ible-files unstyled">
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/F5M/1N9X/ISCAU54E/F5M1N9XISCAU54E.ino"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="local_Station_v3_1.ino"/><span class="title">local_Station_v3_1.ino</span></a></li>
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FHV/SICE/ISCAU55S/FHVSICEISCAU55S.ino"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="generalFunctions.ino"/><span class="title">generalFunctions.ino</span></a></li>
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FMY/D2BG/ISCAU56L/FMYD2BGISCAU56L.ino"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="sensors.ino"/><span class="title">sensors.ino</span></a></li>
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FJ7/C1Y7/ISCAU55R/FJ7C1Y7ISCAU55R.ino"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="printDisplay.ino"/><span class="title">printDisplay.ino</span></a></li>
<li class="file-info clearfix"><a href="http://www.instructables.com/files/orig/FI6/G8ME/ISCAU56P/FI6G8MEISCAU56P.h"><img src="https://i0.wp.com/www.instructables.com/static/defaultIMG/file.TINY.gif" alt="stationDefines.h"/><span class="title">stationDefines.h</span></a></li>
</ul>
</div>
</div>
<div class="step-container"><div class="step-body"></div>
</div>
<div class="step-container"><h2 id="step8" class="step-title">1.8: Small Form Factor (colocando tudo na “caixinha”)</h2>
<div id="photoset-SNJHUKEISAURN85" class="photoset"><div class="photoset-row cols-2"><div class="photoset-cell image-cell"></div>
<div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a href="http://www.instructables.com/file/FT0FKKWISCARMCW/" target="_blank"><img src="https://cdn.instructables.com/FT0/FKKW/ISCARMCW/FT0FKKWISCARMCW.MEDIUM.jpg?width=703" width="703" class="align-full"/></a></div>
</div>
</div>
<div class="photoset-row cols-3"></div>
</div>
<div class="step-body"><p class="p1"><span class="s1">Uma vez que possuímos nosso protótipo funcional, vamos montar-lo de uma forma melhor, usando-se um “Shield” para o Arduino Nano (no caso, um fabricado pela “Funduino”) e uma caixa plástica, o que ajudará nos testes externos. A grande vantagem de se usar um shield para o Nano, é que cada componente fica melhor montado reduzindo os maus contatos e ruídos, além da facilidade de se ter todos os componentes principais reunidos em uma pequena caixa de plástico.</span></p>
<p><img class="lazy-img alignleft" src="https://cdn.instructables.com/F9Z/2FPF/ISCARMCX/F9Z2FPFISCARMCX.MEDIUM.jpg" alt="IMG_4781.JPG" width="130" height="171"/></p>
<p class="p1"><span class="s1">Se você estiver usando o DHT isolado (sem ser em um módulo), você adicione um resistor de 10K entre VCC e Signal. Se você estiver usando um módulo sensor, a resistência já se encontra incluído. Para este novo teste usarei o módulo DHT11 que tenho disponível. O resultado para o nosso propósito é o mesmo (apenas não se esqueça de alterar a linha no código para definir o sensor apropriado que você irá usar: <em>#define DHTTYPE DHT11).</em></span></p>
</div>
</div>
<p><img class="lazy-img alignright" src="https://cdn.instructables.com/FJG/AGXG/ISCARNB9/FJGAGXGISCARNB9.SMALL.jpg" alt="57c1b7c767400c7912000c37.jpeg" width="224" height="168"/></p>
<p class="p1"><span class="s1">Faça 4 furos na caixa de plástico para a instalação do LCD (eu o deixei dentro da caixa).</span></p>
<div class="step-container"><div class="step-body"><p>Faça <img class="lazy-img alignleft" src="https://cdn.instructables.com/F0V/BP45/ISCARN7P/F0VBP45ISCARN7P.SMALL.jpg" alt="57c1b7a045bcebf5270006ab.jpeg"/>furos laterais na caixa para que que você possa acessar os sensores, ter acesso ao Nano (seja para a fonte de alimentação externa ou atualizações de SW) e ligar os atuadores (Bomba / Lampada) nas saídas de relés</p>
<p><img class=" alignright" src="https://cdn.instructables.com/FCC/FCIG/ISCB4JPU/FCCFCIGISCB4JPU.MEDIUM.jpg" alt="Picture of Changing to a Small Form Factor" width="224" height="157"/></p>
<p class="p1"><span class="s1">Note que para os botões de controle, usei aqui um teclado do tipo membrana de 4 teclas “1 × 4 Key Matrix Membrane Switch”. </span></p>
<p><img class="lazy-img alignleft" src="https://cdn.instructables.com/FSA/T8GU/ISCASBN9/FSAT8GUISCASBN9.SMALL.jpg" alt="IMG_4788.JPG" width="146" height="195"/></p>
<p class="p1"><span class="s1">Você pode decidir a melhor maneira de fixar os componentes na caixa. Eu pessoalmente, gosto desse fixador removível da 3M para facilitar a instalação (veja as foto).</span></p>
</div>
</div>
<div class="step-container"><h2 class="p1"><span class="s1">1.9: Testes funcionais em laboratório</span></h2>
<p class="p2"><span class="s1">Uma vez que tudo está fixada em seu devido lugar e o SW carregado, vamos fazer alguns testes funcionais que simulem diferentes condições de sensores, a fim de se verificar que tudo esteja bem ligado:</span></p>
<p class="p2"><span class="s1">Com luz e temperatura normais, introduzir o higrômetro em um copo com amostra de solo húmido. Observe a foto 1 (Temp é 22oC;. Soil Hum é de 85% e luz é de 80%). Nada deve acontecer. Pump e Lamp devem ser OFF ( “0”).</span></p>
<div class="step-body"><p><img class="photo imgFN09DO0ISCASVGB aligncenter" src="https://cdn.instructables.com/FN0/9DO0/ISCASVGB/FN09DO0ISCASVGB.MEDIUM.jpg" alt="Picture of Funcional tests" width="450" height="336"/></p>
<p class="p1"><span class="s1">Mantendo-se a mesma luz e temperatura, passemos a sonda para o copo com amostra de solo seco. Na foto 2, você pode observar que a bomba foi ligada (Primeiro aparecerá o “X” e depois o “1” durante algum tempo, tal como definido no programa).</span></p>
<p><img class="lazy-img aligncenter" src="https://cdn.instructables.com/F8K/MPBO/ISCASWWX/F8KMPBOISCASWWX.MEDIUM.jpg" alt="57c1e6574fbadef414000d35.jpeg" width="450" height="338"/></p>
<p class="p1"><span class="s1">Agora, como mostrado na foto 3, o LDR foi coberto com um pano preto e a luminosidade decresceu para 19%. </span><span class="s2">Neste caso, apesar do fato de que o solo esteja seco, a bomba não ligará, porque o ArduFarmBot entenderá que é à noite.</span></p>
</div>
</div>
<p><img class="lazy-img aligncenter" src="https://cdn.instructables.com/F79/YICG/ISCASXKW/F79YICGISCASXKW.MEDIUM.jpg" alt="57c1e71ddeafa41a5b0007af.jpeg" width="450" height="338"/></p>
<p class="p1"><span class="s1">Na foto 4, colocaremos gelo no fundo da nossa caixa, junto ao sensor DHT. A temperatura desceu a 12oC e a lâmpada foi ligada.</span></p>
<p><img class="lazy-img aligncenter" src="https://cdn.instructables.com/F0B/6EYW/ISCASZ1U/F0B6EYWISCASZ1U.MEDIUM.jpg" alt="57c1e801deafa41a5b0007b5.jpeg" width="450" height="338"/></p>
<div class="step-container"><div class="step-body"><p class="p1"><span class="s1">E por último, na foto 5 manteremos o gelo, mas mudaremos a sonda novamente para a amostra de solo húmido. Neste caso apesar do fato de estar frio, de acordo com a matriz, a lâmpada permanece desligada.</span></p>
<p><img class="lazy-img aligncenter" src="https://cdn.instructables.com/FPV/LL5D/ISCAT0SO/FPVLL5DISCAT0SO.MEDIUM.jpg" alt="57c1e8f84fbadef21e00044f.jpeg" width="450" height="338"/></p>
</div>
</div>
<div class="step-container"><h2 class="step-title"></h2>
<h2 class="p1"><span class="s1">1.10: “Test Drive”: Regando um tomateiro com o ArduFarmBot</span></h2>
<div id="photoset-SP0WF1YISCATWDQ" class="photoset"><div class="photoset-row cols-1"><div class="photoset-cell image-cell"><div class="photoset-item photoset-image"><a class="photoset-link" href="http://www.instructables.com/file/F4JUXPIISCATZ3V/"><img class=" alignleft" src="https://cdn.instructables.com/F4J/UXPI/ISCATZ3V/F4JUXPIISCATZ3V.MEDIUM.jpg" alt="Picture of "Test Drive": Watering a Tomato plant with ArduFarmBot" width="230" height="173"/></a></div>
</div>
</div>
</div>
<div class="step-body"><p class="p1"><span class="s1">Para os primeiros testes reias, liguei uma bomba elétrica que tinha disponível (no projeto final a bomba será uma pequena bomba DC de 9V). Este primeiro teste é só para ver</span><span class="s2"> como o projeto vai funcionar, então não se preocupam com as gotas que você vai ver no vídeo ao lado).</span></p>
</div>
</div>
<div class="step-container"><div class="step-body"><div class="jetpack-video-wrapper"><a href="https://youtu.be/kIQePtzSjP0">https://youtu.be/kIQePtzSjP0</a></div>
<div class="jetpack-video-wrapper"></div>
</div>
</div>
<div class="step-container"><p class="p2"></p>
<div class="step-body"><h2 class="p1"><span class="s1">1.11: O ArduFarmBot em ação</span></h2>
<p class="p2"><span class="s1">Com base em tudo o que nós aprendemos aqui, o passo agora será colocar o ArduFarmBot para controlar sua plantação verdadeira de tomate. Com base nesta experiência real, calibraremos e definiremos melhor os sensores e parâmetros do projeto. As fotos aqui dão uma idéia da sequência da preparação da terra e a introdução das sementes. Essa parte do projeto está a cargo de nosso “Chef” Maurício! Todos os detalhes dos testes reais serão explorados em na 3a. e última parte do projeto.</span></p>
<p><span class="s1"> <a href="https://mjrobot.files.wordpress.com/2016/08/maufarmcolagem.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/08/maufarmcolagem.png?w=840&width=703" width="703" class="align-full"/></a></span></p>
</div>
</div>
<div class="step-container">O filme abaixo mostra o ArduFarmBot em ação:</div>
<div class="step-container"></div>
<div class="step-container"><div class="step-container"><div class="step-body"><p class="p1"><span class="s1"><a class="ytp-share-panel-link ytp-no-contextmenu" target="_blank" title="Share link" href="https://youtu.be/HBhg5NtLcs0">https://youtu.be/HBhg5NtLcs0</a></span></p>
<p class="p1"></p>
<p class="p1"><span class="s1">Agora é só torcer para que tudo de certo e possamos ter uma grande salada no final do projeto!!!! Salut! ;-)</span></p>
</div>
</div>
<div class="step-container"><div class="step-container"><h2 class="p1"></h2>
<h2 class="p1"><span class="s1">1.12: Parte 1 Conclusão</span></h2>
<p class="p2"><span class="s1"><a href="https://mjrobot.files.wordpress.com/2016/09/mjrobot-and-ardufarmbot.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/09/mjrobot-and-ardufarmbot.png?w=840&width=703" width="703" class="align-full"/></a>Em breve publicaremos a segunda parte do nosso projeto que será a conexão com a internet e sua aplicação na plantação de tomate.</span></p>
<p>Como sempre, espero que este projeto ajude outras pessoas a encontrar seu caminho no apaixonante mundo da eletrônica, do IoT e dos robôs!</p>
<p>Para mais tutoriais, por favor visite meu blog: <a href="https://mjrobot.org/" target="_blank">MJRoBot.org</a></p>
<p>Um abraço e até o próximo post!</p>
<p>Obrigado</p>
<p class="p2"><span class="s1">Saludos desde el sur del mundo!</span></p>
<p class="p2">Marcelo e Maurício</p>
</div>
</div>
</div>
<div class="step-container"></div>
</div>
</div>Tutorial: Controlando o robô aspirador “Roomba” com Arduino e Androidtag:labdegaragem.com,2016-07-04:6223006:BlogPost:5472022016-07-04T23:06:25.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p></p>
<div class="post-thumbnail"><a href="https://mjrobot.files.wordpress.com/2016/07/img_4302.jpg?w=1200&h=0&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2016/07/img_4302.jpg?w=1200&h=0&crop=1&width=700" width="700"></img></a></div>
<div class="entry-content"><p><br class="Apple-interchange-newline"></br><span>Como um dos vencedores do concurso “Robotics 2016” do Instructables, recebi como prêmio da empresa iRobot, um robô aspirador Roomba Create2. Neste post, vou contar um pouco de minhas primeiras aventuras com o garoto!</span></p>
<p>O Create 2 é uma robusta e…</p>
</div>
<p></p>
<div class="post-thumbnail"><a href="https://mjrobot.files.wordpress.com/2016/07/img_4302.jpg?w=1200&h=0&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/07/img_4302.jpg?w=1200&h=0&crop=1&width=700" width="700" class="align-full"/></a></div>
<div class="entry-content"><p><br class="Apple-interchange-newline"/><span>Como um dos vencedores do concurso “Robotics 2016” do Instructables, recebi como prêmio da empresa iRobot, um robô aspirador Roomba Create2. Neste post, vou contar um pouco de minhas primeiras aventuras com o garoto!</span></p>
<p>O Create 2 é uma robusta e relativamente acessível plataforma para o desenvolvimento de projetos na área da robótica (pelo menos nos EUA, onde custa cerca de US $ 200). O Create2 é na verdade um Robô Aspirador de pó “Roomba” da série 660 restaurado que permite uma variedade de métodos de programação. No Brasil, mais e mais se torna comum este tipo de eletrodomésticos ( então é só esperar a mãe sair de casa e fazer alguma experiências com o rapaz ;-)</p>
<p></p>
<p>Para começar, usei um Arduino e um aplicativo Android para poder mover o robô por aí. Neste primeiro tutorial, explorarei como conectar o Arduino com o Roomba via porta serial e como comandar seus motores, LEDs e som. Em projectos futuros, explorarei seus sensores e usarei um Raspberry Pi para conectar o Roomba com a internet.</p>
<p>Abaixo, um rápido vídeo mostrando os meus primeiros resultados programando o Roomba:</p>
<div class="jetpack-video-wrapper"><span style="font-size: 1em;"><a href="https://www.youtube.com/watch?v=bEIQpJCQcgM">https://www.youtube.com/watch?v=bEIQpJCQcgM</a></span></div>
<div class="jetpack-video-wrapper"><br/> <br/><h4>PASSO 1: LISTA DE MATERIAIS</h4>
</div>
<h4><img class=" wp-image-5406 alignright" src="https://mjrobot.files.wordpress.com/2016/07/bom.png?w=265&h=201" alt="BoM" width="265" height="201"/></h4>
<ul>
<li>iRobot “Roomba”Create2</li>
<li>Arduino UNO</li>
<li>módulo Bluetooth HC-06</li>
<li>Botão (“Push0Button”)</li>
<li>Protobard e cabos de conecção.</li>
</ul>
<p> </p>
<br/> <br/>
<h4>PASSO 2: O ROOMBA CREATE2</h4>
<p>O Roomba é um robô do tipo diferencial, com 2 rodas e um “caster”</p>
<p><img class=" wp-image-5442 alignleft" src="https://mjrobot.files.wordpress.com/2016/07/roomba-wheels.png?w=256&h=247" alt="Roomba Wheels" width="256" height="247"/></p>
<p> </p>
<p> </p>
<p>Sua velocidade vai até 500 mm/s e pode ser comandado para ir tanto para a frente como para trás.</p>
<p> </p>
<p>Para sinalização, podemos contar com 4 displays de sete segmentos e 5 LEDs:<img class=" wp-image-5408 aligncenter" src="https://mjrobot.files.wordpress.com/2016/07/create-sensors-leds.png?w=579&h=464" alt="Create-Sensors-LEDS" width="579" height="464"/></p>
<ul>
<li>Limpar (Clean)</li>
<li>Local (Spot)</li>
<li>Doca (Dock)</li>
<li>Aviso (Warning)</li>
<li>Sugeira (Dirt / Debris)</li>
</ul>
<p>Como sensores internos, temos entre outros:</p>
<ul>
<li>Detector de degrau (Cliff) (4 à frente)</li>
<li>Detectores de colisão (2 na frente)</li>
<li>Codificadores de giro das rodas</li>
</ul>
<p> </p>
<p>Para a programação, deve ser usado o documento de referencia: <a href="http://www.irobotweb.com/~/media/MainSite/PDFs/About/STEM/Create/iRobot_Roomba_600_Open_Interface_Spec.pdf?la=en">iRobot® Create® 2 Open Interface (OI) </a>.</p>
<p>O Roomba possui 3 modos de programação:</p>
<ul>
<li><span>Modo de segurança (Safe)</span>:<br/> Libera o controle total do Roomba, com a excepção das seguintes condições de segurança:<p></p>
<ul>
<li>Carregador de batería conectado e ligado.</li>
<li>A detecção de uma queda de roda (ocorre quando se “levanta o Roomba do chão”).</li>
<li>A detecção de um degrau de escada por exemplo, enquanto se move para a frente (ou movendo-se para trás com um raio de giro pequeno).</li>
</ul>
</li>
</ul>
<p>Se uma das condições de segurança acima ocorrem enquanto o Roomba está em modo de segurança, Roomba para todos os motores e reverte para o modo passivo.</p>
<ul>
<li><span>Modo passivo (Passive):</span><br/> Ao enviar o comando Iniciar (“Start”) ou qualquer um dos comandos do modo de limpeza (por exemplo, “Spot”, “Clean”, “Seek Dock”), o Roomba entra em modo passivo. Quando o Roomba está em modo passivo, você pode solicitar e receber dados utilizando qualquer um dos comandos de sensores, mas você não pode mudar os parâmetros de comando dos atuadores (motores, som, luzes, saídas digitais, etc.) .</li>
</ul>
<ul>
<li><span>Modo completo (Full):</span><br/> Libera o controle completo do Roomba, a todos os seus atuadores e a todas as condições de segurança que são restritos quando o robô está em modo de segurança descritas no modo Safe.</li>
</ul>
<br/> <br/>
<h4>PASSO 3: A COMUNICAÇÃO SERIAL</h4>
<p>Para a comunicação entre o Roomba e o Arduino, será utilizada a porta serial de ambos. Por padrão, o Roomba se comunica a 115.200 bauds, mas para uma melhor comunicação com o Arduino, vamos modificar-lo para 19.200 bauds.</p>
<p>Existem 2 maneiras de se definir a taxa de transmissão do Roomba :</p>
<ul>
<li>Durante o desligamento do Roomba, continue a manter pressionado o botão central POWER/CLEAN, mesmo após a luz se apagar. Após cerca de 10 segundos, o Roomba tocará uma música com tons descendentes. A partir daí, o Roomba irá comunicar-se a 19.200 bauds até que o processador perda a energia da bateria ou a taxa de transmissão seja explicitamente alterada através de programação.</li>
<li>Usar o pino 5 no conector Mini-DIN (Baud Rate Change pin) para alterar a taxa de transmissão do Roomba. Depois de ligar o Roomba, espere 2 segundos; em seguida, aplique um pulso de nivel baixo no pin5 três vezes. Cada pulso deve durar entre 50 e 500 milissegundos. O Roomba irá comunicar-se a 19200 bauds até que o processador perca a energia da bateria ou a taxa de transmissão seja explicitamente alterada por SW.</li>
</ul>
<p>O diagrama abaixo mostra como o Arduino deve ser conectado ao conector Mini-DIN do Roomba:</p>
<p><img class="alignnone size-full wp-image-5414 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/07/serial_conn.png?w=840" alt="Serial_Conn"/></p>
<p>Par se ter acesso ao Mini-DIN se deve remover a parte superior do Create 2 (capa verde), ou simplesmente fazer um furo na mesma.</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979593262?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979593262?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<br/><br/>
<h4>PASSO 4: INICIALIZANDO O ROMBA</h4>
<p>O primeiro passo a ser feito na programação de um Roomba é:</p>
<ul>
<li>“Acordar” o robô</li>
<li>Iniciar e definir o modo de operação (Safe ou Full)</li>
</ul>
<p>Para acordar o Roomba, devemos enviar um pulso baixo para o pino 5 do Mini-DIN (detectar dispositivo de entrada), como mostrado n</p>
<p>a função abaixo (ddPin é o pin 5 do Arduino conectado ao pin% do Roomba):</p>
<p></p>
<p><span style="color: #993300;"><em>void wakeUp (void)</em></span></p>
<p><span style="color: #993300;"><em>{</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(ddPin, HIGH);</em></span></p>
<p><span style="color: #993300;"><em> delay(100);</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(ddPin, LOW);</em></span></p>
<p><span style="color: #993300;"><em> delay(500);</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(ddPin, HIGH);</em></span></p>
<p><span style="color: #993300;"><em> delay(2000);</em></span></p>
<p><span style="color: #993300;"><em>}</em></span></p>
<p></p>
<p>Para iniciar o Roomba, sempre devem ser enviados 2 códigos :</p>
<p>“START” [128] e o modo, no nosso caso “modo de segurança” [131]. Se você quizer o “modo completo”, deve enviar o código [132].</p>
<p></p>
<p><em><span style="color: #993300;">void startSafe()</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(128); //Start</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(131); //Safe mode</span></em></p>
<p><em><span style="color: #993300;"> delay(1000);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<span style="font-size: 1em;"><span style="font-size: 1em;"><br/> <br/></span></span>
<h4>PASSO 5: ACIONAR OS LEDS E DISPLAY</h4>
<h5>Ligando os LEDs</h5>
<p>Conforme descrito na introdução, o Roomba possui 5 LEDs:</p>
<ul>
<li>POWER/CLEAN (bicolor vermelho / verde e intensidade controlada)</li>
<li>SPOT (Verde, intensidade fixa)</li>
<li>DOVK (verde, a intensidade fixa)</li>
<li>WARNING / Check (Laranja, intensidade fixa)</li>
<li>DIRT (azul, intensidade fixa)</li>
</ul>
<p>Todos os LEDs podem ser comandados usando o código [139]</p>
<p>Para controlar o LED POWER/CLEAN, você deve enviar dois bytes de dados para o Roomba: “cor” e “intensidade”.</p>
<ul>
<li>Cor:<ul>
<li>Verde = 0</li>
<li>Laranja = 128</li>
<li>vermelho = 255</li>
</ul>
</li>
<li>Intensidade:<ul>
<li>Min = 0</li>
<li>Max = 255</li>
</ul>
</li>
</ul>
<p>A função <span><em>setPowerLED (byte setColor, byte setIntensity)</em></span> faz isso automaticamente:</p>
<p></p>
<p><em><span style="color: #993300;">void setPowerLED(byte setColor, byte setIntensity)</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> color = setColor;</span></em></p>
<p><em><span style="color: #993300;"> intensity = setIntensity;</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(139);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write((byte)0x00);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write((byte)color);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write((byte)intensity);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>Por exemplo, para acender o LED POWER com cor de laranja e na metade de sua intensidade maxima, você pode chamar a função como abaixo:</p>
<p></p>
<p><em><span style="color: #993300;">setPowerLED (128, 128);</span></em></p>
<p></p>
<p>Para acender os restantes 4 LEDs, devem ser utilizadas as funções:</p>
<p></p>
<p><em><span style="color: #993300;">setDebrisLED (ON);</span></em></p>
<p><em><span style="color: #993300;">setDockLED (ON);</span></em></p>
<p><em><span style="color: #993300;">setSpotLED (ON);</span></em></p>
<p><em><span style="color: #993300;">setWarningLED (ON);</span></em></p>
<p></p>
<p>Todas as funções acima tem um código semelhante a este:</p>
<p></p>
<p><em><span style="color: #993300;">void setDebrisLED(bool enable)</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> debrisLED = enable;</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(139);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write((debrisLED ? 1 : 0) + (spotLED ? 2 : 0) + (dockLED ? 4 : 0) + (warningLED ? 8 : 0));</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write((byte)color);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write((byte)intensity);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>Basicamente, a diferença estará na linha:</p>
<p></p>
<p><em><span style="color: #993300;">debrisLED = enable;</span></em></p>
<p></p>
<p><img class=" wp-image-5421 alignleft" src="https://mjrobot.files.wordpress.com/2016/07/img_4305.jpg?w=243&h=324" alt="IMG_4305" width="243" height="324"/></p>
<p></p>
<p>a qual deverá ser alterada permitindo (“enabling”) que cada um dos outros LEDs (spotLED, dockLED, warningLED) acenda.</p>
<h5>Envio de mensagens a serem mostradas</h5>
<p>O Roomba possui quatro Displays de 7 Segmentos que você podem ser usados para enviar mensagens de duas maneiras diferentes:</p>
<ul>
<li>Código [163]: LEDs com dígitos numéricos (“Raw”)</li>
<li>Código [164]: LEDs com dígitos ASCII (aproximação de letras e códigos especiais)</li>
</ul>
<p>Para exibir números é muito facil. Você apenas deve enviar o código [163], seguido dos 4 dígitos a serem exibidos. A função:</p>
<p></p>
<p><em><span style="color: #993300;">setDigitLEDs (digit1 byte, digit2 byte, digit3 byte, byte digit4)</span></em></p>
<p></p>
<p>faz isso para você:</p>
<p></p>
<p><em><span style="color: #993300;">void setDigitLEDs(byte digit1, byte digit2, byte digit3, byte digit4)</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(163);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(digit1);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(digit2);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(digit3);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(digit4);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>Por exemplo, para exibir “1, 2, 3, 4”, basta chamar a função:</p>
<p></p>
<p><em><span style="color: #993300;">setDigitLEDs (1, 2, 3, 4);</span></em></p>
<p></p>
<p>Com o código [164], é possível aproximação de envio de ASCII.</p>
<p>A função:<em><span> setDigitLEDFromASCII(<span><em>byte digit, char letter</em></span>)</span> </em>faz isso para nós:</p>
<p></p>
<p><em><span style="color: #993300;">void setDigitLEDFromASCII(byte digit, char letter)</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> switch (digit)</span></em></p>
<p><em><span style="color: #993300;"> {</span></em></p>
<p><em><span style="color: #993300;"> case 1:</span></em></p>
<p><em><span style="color: #993300;"> digit1 = letter;</span></em></p>
<p><em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case 2:</span></em></p>
<p><em><span style="color: #993300;"> digit2 = letter;</span></em></p>
<p><em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case 3:</span></em></p>
<p><em><span style="color: #993300;"> digit3 = letter;</span></em></p>
<p><em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case 4:</span></em></p>
<p><em><span style="color: #993300;"> digit4 = letter;</span></em></p>
<p><em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> }</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(164);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(digit1);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(digit2);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(digit3);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(digit4);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>Para simplificar, criei uma nova função que pode ser utilizada para enviar os 4 dígitos ao mesmo tempo:</p>
<p></p>
<p><em><span style="color: #993300;">void writeLEDs (char a, char b, char c, char d)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> setDigitLEDFromASCII(1, a);</span></em><br/> <em><span style="color: #993300;"> setDigitLEDFromASCII(2, b);</span></em><br/> <em><span style="color: #993300;"> setDigitLEDFromASCII(3, c);</span></em><br/> <em><span style="color: #993300;"> setDigitLEDFromASCII(4, d);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>Por exemplo, para exibir “STOP”, você deve chamar a função:</p>
<p><em><span style="color: #993300;">writeLEDs ( 's', 't', 'o', 'p');</span></em></p>
<p></p>
<p><img class="alignnone wp-image-5420" src="https://mjrobot.files.wordpress.com/2016/07/img_4304.jpg?w=347&h=462" alt="IMG_4304" width="347" height="462"/></p>
<span style="font-size: 1em;"><span style="font-size: 1em;"><br/> <br/></span></span>
<h4>PASSO 6: PILOTANDO O ROOMBA PELA CASA</h4>
<p>Para sua mobilidade, o Roomba possui 2 motores DC independentes que podem ser programados para rodar a uma velocidade de até 500 mm/s. Existem vários comandos que podem ser usados para dirigir o robô. Os principais são:</p>
<ol>
<li>Código [137]: Drive ==> devem ser enviados: +/- velocidade em mm/s e +/- Radius em mm</li>
<li>Código [145]: Direct Drive ==> deve ser enviado velocidade à Esquerda/Direita em mm/s (+ para a frente e – para trás)</li>
<li>Código [146]: Drive PWM ==> devem ser enviados +/- dados PWM individualmente para as rodas esquerda e direita.</li>
</ol>
<p>Abaixo o código para essas 3 opções descritas anteriormente:</p>
<p></p>
<p><em><span style="color: #993300;">void drive(int velocity, int radius)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> clamp(velocity, -500, 500); //def max and min velocity in mm/s</span></em><br/> <em><span style="color: #993300;"> clamp(radius, -2000, 2000); //def max and min radius in mm</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(137);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(velocity >> 8);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(velocity);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(radius >> 8);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(radius);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p><em><span style="color: #993300;">//---------------------------------------------------------------</span></em></p>
<p><em><span style="color: #993300;">void driveWheels(int right, int left)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> clamp(right, -500, 500);</span></em><br/> <em><span style="color: #993300;"> clamp(left, -500, 500);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(145);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(right >> 8);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(right);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(left >> 8);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(left);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p><em><span style="color: #993300;">//---------------------------------------------------------------</span></em><br/> <em><span style="color: #993300;">void driveWheelsPWM(int rightPWM, int leftPWM)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> clamp(rightPWM, -255, 255);</span></em><br/> <em><span style="color: #993300;"> clamp(leftPWM, -255, 255);</span></em></p>
<p><em><span style="color: #993300;"> Roomba.write(146);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(rightPWM >> 8);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(rightPWM);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(leftPWM >> 8);</span></em><br/> <em><span style="color: #993300;"> Roomba.write(leftPWM);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p></p>
<p><span>Note que a função “clamp” define os valores máximos e mínimos que são permitidos para como entrada. Essa função é definida no <em><span style="color: #993300;">arquivo</span></em></span><em><span style="color: #993300;">rombaDefines.h :</span></em></p>
<p></p>
<p><em><span style="color: #993300;">#define clamp(value, min, max) (value < min ? min : value > max ? max : value)</span></em></p>
<p></p>
<p>Usando os códigos descritos acima, funções mais simples podem ser criadas para mover o Roomba:</p>
<p></p>
<p><em><span style="color: #993300;">void turnCW(unsigned short velocity, unsigned short degrees)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> drive(velocity, -1);</span></em><br/> <em><span style="color: #993300;"> clamp(velocity, 0, 500);</span></em><br/> <em><span style="color: #993300;"> delay(6600);</span></em><br/> <em><span style="color: #993300;"> drive(0,0);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p><em><span style="color: #993300;">//---------------------------------------------------------------</span></em><br/> <em><span style="color: #993300;">void turnCCW(unsigned short velocity, unsigned short degrees)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> drive(velocity, 1);</span></em> <br/> <em><span style="color: #993300;"> clamp(velocity, 0, 500);</span></em><br/> <em><span style="color: #993300;"> delay(6600);</span></em><br/> <em><span style="color: #993300;"> drive(0,0);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p><em><span style="color: #993300;">//---------------------------------------------------------------</span></em><br/> <em><span style="color: #993300;">void driveStop(void)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> drive(0,0);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p><em><span style="color: #993300;">//---------------------------------------------------------------</span></em><br/> <em><span style="color: #993300;">void driveLeft(int left)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> driveWheels(left, 0);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p><em><span style="color: #993300;">//---------------------------------------------------------------</span></em><br/> <em><span style="color: #993300;">void driveRight(int right)</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> driveWheels(0, right);</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p>Note-se que para se obter um valor de ângulo correto, o argumento da função “delay” deve ser calculada especificamente para uma dada velocidade (o método de tentativa e erro é a melhor opção aqui).</p>
<p>Abaixo alguns exemplos que podem ser utilizados para testar os motores:</p>
<p></p>
<p><em><span style="color: #993300;">turnCW (40, 180); // spin clockwise 180 degrees and stop</span></em></p>
<p><em><span style="color: #993300;">driveWheels(20, -20); // spin</span></em></p>
<p><em><span style="color: #993300;">driveLeft(20); // turning left</span></em></p>
<p></p>
<span style="font-size: 1em;"><span style="font-size: 1em;"><a href="https://mjrobot.files.wordpress.com/2016/07/img_4307.jpg?w=253&h=338" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/07/img_4307.jpg?w=253&h=338&width=253" width="196" class="align-left" height="262"/></a></span></span><br />
<p> </p>
<p>Para testar os motores, é bom adicionar um botão externo (no meu caso ligado ao Arduino pino 12), de modo a que você possa baixar o código para o Arduino, iniciando o Roomba, mas parando a execução até que o botão seja é pressionado.</p>
<p> </p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p>Abaixo, simples exemplo de um código de testes para os motores utilizando-se Arduino (observe que para o codigo ser executado, funções e definições discutidas nos steps anteriores deverão ser utilizadas):</p>
</div>
<div class="entry-content"></div>
<div class="entry-content"><p><em><span style="color: #993300;">#include "roombaDefines.h"</span></em><br/> <em><span style="color: #993300;">#include <SoftwareSerial.h></span></em></p>
<p><em><span style="color: #993300;">// Roomba Create2 connection</span></em><br/> <em><span style="color: #993300;">int rxPin=10;</span></em><br/> <em><span style="color: #993300;">int txPin=11;</span></em><br/> <em><span style="color: #993300;">SoftwareSerial Roomba(rxPin,txPin);</span></em></p>
<p><em><span style="color: #993300;">//---------------------------------------------</span></em><br/> <em><span style="color: #993300;">void setup()</span></em> <br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> Roomba.begin(19200);</span></em></p>
<p><em><span style="color: #993300;"> pinMode(ddPin, OUTPUT);</span></em><br/> <em><span style="color: #993300;"> pinMode(buttonPin, INPUT_PULLUP); // connected to Arduino pin 12 and used for "starting"</span></em></p>
<p><em><span style="color: #993300;"> delay(2000);</span></em></p>
<p><em><span style="color: #993300;"> wakeUp (); // Wake-up Roomba</span></em><br/> <em><span style="color: #993300;"> startSafe(); // Start Roomba in Safe Mode</span></em></p>
<p><em><span style="color: #993300;"> while (digitalRead(buttonPin)) { } // wait button to be pressed to continous run code</span></em></p>
<p><em><span style="color: #993300;"> turnCW (40, 180); //test Roomba spin clock-wise 180 degrees and stop</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p><em><span style="color: #993300;">//---------------------------------------------</span></em><br/> <em><span style="color: #993300;">void loop()</span></em> <br/> <em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
</div>
<div class="entry-content"><br/> <br/><h4>PASSO 7: CONTROLANDO ROOMBA VIA BLUETOOTH</h4>
<p>Para completar a nossa primeira parte do projeto, vamos instalar um módulo Bluetooth (HC-06) para a nosso Arduino. O diagrama abaixo mostra como fazê-lo.</p>
<p><img class="alignnone size-full wp-image-5413 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/07/serial_bt_conn.png?w=840" alt="Serial_BT_Conn"/></p>
<p>Normalmente, o HC-06 é fornecido de fábrica com uma taxa de transmissão de 9600 bauds. É importante que você o altere para 19.200, de maneira a ser compatível com a velocidade de comunicação utilizada pelo Arduino-Roomba. Você pode fazer isso enviando um comando AT para o módulo (AT + BAUD5 onde “5” é o código para 19.200).</p>
<p>Se você tem alguma dúvida sobre como o HC-06 trabalha, por favor dê uma olhada no meu tutorial: <a href="https://mjrobot.org/2016/01/30/conectando-coisas-atraves-do-bluetooth/" target="_blank">Conectando “coisas” através do Bluetooth</a></p>
<p>Para guiar o Roomba, vamos utilizar um aplicativo genérico para controle de robôs móveis que desenvolvi a partir do MIT AppInventor 2: <a href="https://play.google.com/store/apps/details?id=appinventor.ai_mjrovai.MJRoBot_II_BT_Command_V2&hl=en" target="_blank">“MJRoBot BT Remote Control”</a>. <br/> O aplicativo pode ser baixado gratuitamente a partir da loja Google.</p>
<br/>
<p><img src="https://mjrobot.files.wordpress.com/2016/05/screenshot_2015-12-11-20-24-01.jpg?w=378&h=605&crop=1&width=296" width="300" class="align-right" height="480"/></p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/07/04/controlando-o-robo-aspirador-roomba-com-arduino-e-android/img_4309/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/07/img_4309.jpg?w=454&h=605&crop=1&width=265" width="351" class="align-left" height="468"/></a></div>
</div>
</div>
</div>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p>O aplicativo tem uma interface simples, o que lhe permite enviar comandos para o módulo de BT em ambos, modo texto ou directamente através de botões pré-programados (cada vez que um botão é pressionado, um caracter é enviado):</p>
<ul>
<li>w: Foreward</li>
<li>s: Backward</li>
<li>d: Right</li>
<li>a: Left</li>
<li>f: Stop</li>
<li>p: ON / OFF (não utilizado nesta primeira parte)</li>
<li>m: manual / automatic (utilizado para reiniciar o Roomba caso ele esteje em modo de segurança e encontre um obstáculo como um degrau por exemplo)</li>
<li>+: Velocidade Up</li>
<li>-: Speed Down</li>
</ul>
<p>Você também pode enviar outros comandos como texto, se necessário. Há também uma janela de texto para exibição de mensagens recebidas a partir do módulo de BT. Esta característica é muito importante durante a fase de testes, pode ser usada da mesma forma que o “Serial Monitor” do PC.</p>
<p>A função <em><span>loop ()</span></em> do código será a responsável pela “escuta” do dispositivo bluetooth e dependendo do comando recebido, tomar uma ação:</p>
<p><em><span style="color: #993300;">void loop()</span></em> <br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> checkBTcmd(); // verify if a comand is received from BT remote control</span></em><br/> <em><span style="color: #993300;"> manualCmd ();</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>A função checkBTcmd () é mostrada abaixo:</p>
<p><em><span style="color: #993300;">void checkBTcmd() // verify if a command is received from BT remote control</span></em><br/> <em><span style="color: #993300;">{</span></em> <br/> <em><span style="color: #993300;"> if (BT1.available())</span></em> <br/> <em><span style="color: #993300;"> {</span></em> <br/> <em><span style="color: #993300;"> command = BT1.read();</span></em><br/> <em><span style="color: #993300;"> BT1.flush();</span></em><br/> <em><span style="color: #993300;"> }</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p>Uma vez que um comando é recebido, a função manualCmd () irá tomar as medidas apropriadas:</p>
<p></p>
<p><em><span style="color: #993300;">void manualCmd()</span></em><br/> <em><span style="color: #993300;">{</span></em><br/> <em><span style="color: #993300;"> switch (command)</span></em><br/> <em><span style="color: #993300;"> {</span></em></p>
<p><em><span style="color: #993300;"> case 'm':</span></em> <br/> <em><span style="color: #993300;"> startSafe();</span></em><br/> <em><span style="color: #993300;"> Serial.print("Roomba in Safe mode");</span></em><br/> <em><span style="color: #993300;"> BT1.print("Roomba BT Ctrl OK - Safe mode");</span></em><br/> <em><span style="color: #993300;"> BT1.println('\n');</span></em><br/> <em><span style="color: #993300;"> command = 'f';</span></em><br/> <em><span style="color: #993300;"> playSound (3);</span></em><br/> <em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case 'f':</span></em> <br/> <em><span style="color: #993300;"> driveStop(); //turn off both motors</span></em><br/> <em><span style="color: #993300;"> writeLEDs ('s', 't', 'o', 'p');</span></em><br/> <em><span style="color: #993300;"> state = command;</span></em><br/> <em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case 'w':</span></em> <br/> <em><span style="color: #993300;"> drive (motorSpeed, 0);</span></em> <br/> <em><span style="color: #993300;"> writeLEDs (' ', 'g', 'o', ' ');</span></em><br/> <em><span style="color: #993300;"> state = command;</span></em> <br/> <em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case 'd':</span></em> <br/> <em><span style="color: #993300;"> driveRight(motorSpeed);</span></em><br/> <em><span style="color: #993300;"> writeLEDs ('r', 'i', 'g', 'h');</span></em><br/> <em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case 'a':</span></em> <br/> <em><span style="color: #993300;"> driveLeft(motorSpeed);</span></em><br/> <em><span style="color: #993300;"> writeLEDs ('l', 'e', 'f', 't');</span></em><br/> <em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case 's':</span></em> <br/> <em><span style="color: #993300;"> drive (-motorSpeed, 0);</span></em><br/> <em><span style="color: #993300;"> writeLEDs ('b', 'a', 'c', 'k');</span></em><br/> <em><span style="color: #993300;"> state = command;</span></em><br/> <em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case '+':</span></em> <br/> <em><span style="color: #993300;"> if (state == 'w')</span></em><br/> <em><span style="color: #993300;"> {</span></em><br/> <em><span style="color: #993300;"> motorSpeed = motorSpeed + 10;</span></em><br/> <em><span style="color: #993300;"> if (motorSpeed > MAX_SPEED)</span></em> <br/> <em><span style="color: #993300;"> {</span></em> <br/> <em><span style="color: #993300;"> motorSpeed = MAX_SPEED;</span></em><br/> <em><span style="color: #993300;"> }</span></em> <br/> <em><span style="color: #993300;"> command = 'w';</span></em><br/> <em><span style="color: #993300;"> } else {command = state;}</span></em><br/> <em><span style="color: #993300;"> break;</span></em></p>
<p><em><span style="color: #993300;"> case '-':</span></em></p>
<p><em><span style="color: #993300;"> if (state == 'w')</span></em><br/> <em><span style="color: #993300;"> {</span></em><br/> <em><span style="color: #993300;"> motorSpeed = motorSpeed - 10;</span></em><br/> <em><span style="color: #993300;"> }</span></em> <br/> <em><span style="color: #993300;"> if (motorSpeed < MIN_SPEED )</span></em> <br/> <em><span style="color: #993300;"> {</span></em> <br/> <em><span style="color: #993300;"> motorSpeed = MIN_SPEED;</span></em><br/> <em><span style="color: #993300;"> }</span></em><br/> <em><span style="color: #993300;"> command = state;</span></em><br/> <em><span style="color: #993300;"> break;</span></em><br/> <em><span style="color: #993300;"> }</span></em><br/> <em><span style="color: #993300;">}</span></em></p>
<p></p>
<p></p>
<h4>PASSO 8: CONCLUSÃO</h4>
<p>O código Arduino completo e documentos relacionados podem ser encontrados em meu depositário do GitHub:<a href="https://github.com/Mjrovai/Roomba_BT_Ctrl" target="_blank">Roomba_BT_Ctrl</a>.</p>
<p>Observe que nem todos os atuadores e sensores do Roomba foram discutidos neste tutorial. Existem outros motores utilizados especificamente para a limpeza, LEDs utilizados para a programação, botões, sensores, etc.</p>
<p>Várias das funções que criei em meu programa foram baseados na biblioteca Create 2 desenvolvida por Dom Amato. Você pode baixar a biblioteca completa através do link: <a href="https://github.com/brinnLabs/Create2" target="_blank">https://github.com/brinnLabs/Create2</a>.</p>
<p>Minha intenção aqui foi deixar as coisas simples, procurando dar o pontapé inicial para o desenvolvimento de projetos baseados no robô aspirador Roomba. No futuro, pretendo publicar outros tutoriais, usando um Raspberry-Pi, conectando o Roomba à internet, ler seus sensores, etc.</p>
<p>Como sempre, espero que este projeto possa ajudar outras pessoas a encontrar o seu caminho no excitante mundo da eletrônica e da robótica!</p>
<p>Saludos desde o sul do mundo!</p>
<p>Até o próximo post!</p>
<p>Um abraço e obrigado</p>
<p>Marcelo</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979595328?profile=original" target="_self"><img width="250" src="http://storage.ning.com/topology/rest/1.0/file/get/1979595328?profile=RESIZE_320x320" width="250" class="align-full"/></a></p>
<p></p>
</div>Tutorial: Controlando um `robô baseado no Raspberry Pi pela Internettag:labdegaragem.com,2016-06-02:6223006:BlogPost:5383512016-06-02T02:28:25.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<h4><span>Este tutorial procurará fornecer um grande exemplo do fascinante mundo do IoT, onde o que aprenderemos com o robô, poderá ser utilizado para controlar qualquer coisa pela internet!</span></h4>
<h4><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979597360?profile=original" target="_self"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979597360?profile=RESIZE_1024x1024" width="750"></img></a></h4>
<h4>INTRODUÇÃO</h4>
<p>A idéia deste projeto, é criar um robô totalmente controlado pela internet, usando-se o Raspberry Pi como processador. O robô será…</p>
<h4><span>Este tutorial procurará fornecer um grande exemplo do fascinante mundo do IoT, onde o que aprenderemos com o robô, poderá ser utilizado para controlar qualquer coisa pela internet!</span></h4>
<h4><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979597360?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979597360?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></h4>
<h4>INTRODUÇÃO</h4>
<p>A idéia deste projeto, é criar um robô totalmente controlado pela internet, usando-se o Raspberry Pi como processador. O robô será controlado usando comandos de baixo nível escritos com shell scripts, os quais serão por sua vez comandados diretamente por uma página web escrita em HTML. O fato de não usarmos linguagens de alto nível como Python por exemplo, fará com que o robô reaja bem rápido aos comandos recebidos pela página (mesmo quando a internet for lenta).</p>
<p><a href="https://www.youtube.com/watch?v=dUijuTuA78I" target="_blank">Clicando no link</a> , voce poderá ter uma idéia de como ficará o projeto final.</p>
<div class="jetpack-video-wrapper"></div>
<p><span>O projeto será dividido em duas partes, sendo que na p</span><span>arte 1, será onde aprenderemos a:</span></p>
<ul>
<li>Instalar e usar a biblioteca WiringPi para controlar os GPIOs RPi</li>
<li>Controlar motores usando uma H-Bridge</li>
<li>Transformar o RPI em um servidor web</li>
<li>Criar uma pagina em linguagem HTML (e Java Script) para controlar o robô através da Internet</li>
</ul>
<p>Para ir mais longe e fazer com que seu robô tenha uma “visão” real do mundo, você poderá ir para a segunda parte deste tutorial onde você aprenderá:</p>
<ul>
<li>Como gerar stream de vídeo com uma PiCam</li>
<li>Como instalar e usar a biblioteca ServoBlaster</li>
<li>Como controlar servo motores e construir um mecanismo para posicionamento vertical e horizontal da câmera (mecanismo PAM/TILT)</li>
<li>Criar uma página HTML para controlar o posicionamento da câmara através da internet</li>
</ul>
<p> </p>
<p>O diagrama de blocos abaixo mostra a idéia geral para asa duas partes do projeto:</p>
<p><img class="alignnone size-full wp-image-4538 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/06/full-blockdiagram-webrobot.png?w=840" alt="full blockdiagram webrobot"/></p>
<h3>Primeira Parte: Controlando luzes e motores via internet</h3>
<p>O RPI será definido como um servidor web e receberá comandos de uma página HTML. Esses comandos irão alterar o status dos GPIOs, fazendo com que o RPI controle os motores do robô (direcção e velocidade), além de ligar / desligar um LED (simulado o comando digital de qualquer sistema adicional). Como você pode perceber, o robô é na verdade um caso particular de um projeto de IoT. Você pode na verdade controlar o que quiser e esse tutorial tem a intenção de ser o ponto de partida de novas idéias a serem implementadas no futuro.</p>
<p>No diagrama abaixo, uma visão geral do que desenvolveremos nessa primeira parte:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/full-diagram-1.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/full-diagram-1.png?w=840&width=300" width="300" class="align-right"/></a></p>
<h4>LISTA DE MATERIAIS</h4>
<ul>
<li>RaspberryPi modelo 2 ou 3</li>
<li>H-Bridge L293-D</li>
<li>DC Motors (2x)</li>
<li>Bateria de 9V para os motores</li>
<li>Batería de 5V para RPi</li>
<li>LEDs e resistores de 30 ohms</li>
<li>Protoboard e fios</li>
<li>Suporte de acrílico para a motores / eletrônica (pode ser um kit, CDs, etc.)</li>
</ul>
<h4>INSTALAÇÃO DA BIBLIOTECA WIRINGPI</h4>
<p>WiringPi é uma biblioteca escrita em C utilizada para o acesso direto aos GPIOs do RPi. Ela é muito fácil de usar e simplifica muito qualquer projeto envolvendo RPi e eletrônica (“embebed systems”).</p>
<p>A biblioteca WiringPi inclui um utilitário chamado “GPIO” (<a href="http://wiringpi.com/the-gpio-utility" target="_blank">wiringpi.com/the-gpio-utility</a>) que pode ser usado para programar e configurar os pinos GPIO. Você pode usar o utilitário para ler e/ou escrever diretamente nos pinos do RPi a partir de comandos do tipo shell scripts. É possível escrever programas inteiros utilizando-se apenas comandos GPIO em um shell-script.</p>
<p></p>
<p>Para instalar WiringPi:</p>
<p><span> <em><strong><span style="color: #ff6600;">git clone git: //git.drogon.net/wiringPi</span></strong></em></span></p>
<p><em><strong><span style="color: #ff6600;"> cd wiringPi</span></strong></em></p>
<p><em><strong><span style="color: #ff6600;"> ./build</span></strong></em></p>
<p></p>
<p>Para mostrar na tela a versão do utilitário, use o comando:</p>
<p><span class="s1"> <em><strong><span style="color: #ff6600;"> gpio -v</span></strong></em></span></p>
<p></p>
<p>Para ler todos os pinos normalmente acessíveis e apresentar uma tabela com o status dos pinos em diferentes formatos (wiringPi, BCM_GPIO e pinos físicos), você pode usar o comando “<span class="s1"><span><i>gpio read all</i></span></span>“, que cria um gráfico de referência cruzada, com os seus modos e valores atuais. Este comando também irá detectar a versão / modelo da RPI eo impresso o diagrama pino apropriado para o seu Pi.</p>
<p class="p1"><span class="s1"><span><i> <span> <strong><span style="color: #ff6600;">gpio read all</span></strong></span></i></span></span></p>
<p></p>
<p>A tela do monitor abaixo, mostra o resultado após a entrada dos 2 comandos acima.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/fwj8dsaioo5kjvv-large.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/fwj8dsaioo5kjvv-large.jpg?w=840&width=400" width="400" class="align-full"/></a></p>
<p></p>
<p>Por exemplo, para configurar-se um GPIO utilizando-se o esquema BCM_GPIO como OUTPUT, deve ser utilizar o comando:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;"> gpio -g mode 10 out</span></strong></i></span></span></p>
<p></p>
<p>Uma vez que o pino GPIO tenha seu modo definido, você pode definir um estado lógico para o mesmo. No exemplo, o pino passará a um estado lógico HIGH:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">gpio -g write 10 1</span></strong></i></span></span></p>
<p><img class="alignnone size-full wp-image-4609 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/06/gpio-10-set.png?w=840" alt="GPIO-10 set"/></p>
<p>Para teste, instale o catodo de um LED ao pino GPIO.10, adicionando-se um resistor de 330ohm entre seu ânodo e GND. Faça alguns testes para ter certeza que tudo está funcionando.</p>
<p></p>
<p>Além de se poder definir os pinos como saída ou entrada, você também pode definir alguns deles como uma saída do tipo PWM. Este é o caso do pino físico 12 ou GPIO.18.</p>
<p></p>
<p>Para configurar o pino:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;"> gpio -g mode 18 pwm</span></strong></i></span></span></p>
<p>ou</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">gpio mode 1 pwm </span></strong></i></span></span><strong><span style="color: #ff6600;"> </span></strong> NOTA: ( “1”) é o WPI id para GPIO.18</p>
<p></p>
<p>para configurar um valor PWM:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">gpio pwm 1 XXX </span></strong> </i></span>NOTA</span>: [XXX é um valor entre 0 -> 1023]</p>
<p></p>
<p>Exemplo.:</p>
<p class="p1"><span class="s1"><span><i> <span><strong><span style="color: #ff6600;">gpio pwm 1 512</span></strong> </span></i></span></span><span>NOTA: (50% duty-cicle)</span></p>
<p></p>
<p>Para remover a configuração deste pino particularmante:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">gpio unexport 1</span></strong></i></span></span></p>
<p></p>
<p>Para remover a configuração de todos os pinos:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;"> gpio unexportal</span></strong></i></span></span></p>
<h4>CONTROLANDO MOTORES COM O RASPBERRY PI E A BIBLIOTECA WIRINGPI</h4>
<p>Neste ponto, a biblioteca WiringPi está instalado e você pode controlar qualquer GPIO diretamente pela linha de comando no monitor de seu RPi. O próximo passo será criar uma lógica para controlar os motores. Para isso, usaremos uma H-Bridge, o L-293-D. Este H-Bridge pode controlar até 2 motores, sendo que para cada um dos motores, são necessárias 3 entradas :</p>
<ul>
<li><img class=" wp-image-4672 alignleft" src="https://mjrobot.files.wordpress.com/2016/06/h-bridge-block.png?w=273&h=287" alt="H-Bridge block" width="273" height="287"/></li>
</ul>
<p> </p>
<ul>
<li>Motor Esquerdo: “enable”; “Motor +” e “Motor -“</li>
<li>Motor Direito: “enable”; “Motor +” e “Motor -“</li>
</ul>
<p> </p>
<p> </p>
<p>Em Ambos os motores as entradas “enable” estarão conectadas juntas e serão controladas por GPIO.18. Este pino será o responsável pelo controle de velocidade. Se você não necessitar controlar a velocidade, deixe os pinos em “1” (conectados a +5V), por exemplo.</p>
<p></p>
<p>Convencionaremos que, se queremos que o motor esquerdo vá “para a frente”, deveremos configurar o Motor + (M+) em “1” e Motor – (M-) em “0”. Para que o motor gire em no sentido inverso, faremos o contrário: Motor + (M+) em “0” e Motor – (M-) em “1”. <span>A melhor maneira de realmente definir as entradas correctamente para se controlar o sentido do motor, é para testar-las durante montagem do mesmo.</span></p>
<p></p>
<p>Vamos atribuir os GPIOs para as entradas da ponte:</p>
<ul>
<li>Motor esquerdo+: GPIO.5</li>
<li>Motor esquerdo-: GPIO.6</li>
<li>Motor direito +: GPIO.13</li>
<li>Motor direito -: GPIO.19</li>
</ul>
<p></p>
<p>Com base nos pressupostos acima, uma tabela lógica pode ser construída com os possíveis níveis a serem atribuídas aos GPIOs (ver imagem tabela).</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/motor_table.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/motor_table.png?w=840&width=300" width="300" class="align-left"/></a></p>
<p>O próximo passo é a criação de scripts shell para acionar os motores.</p>
<p>Cada script é essencialmente um simples arquivo tipo texto. Quando se tenta executar um arquivo de texto, o sistema operacional buscará pistas para saber se ele é um script ou não, e como lidar com tudo corretamente. Devido a isso, existem algumas orientações que você precisa saber.</p>
<ul>
<li>Cada script deve iniciar com “<span>#!/bin/bash</span>” (O Hash-Bang Hack}</li>
<li>Cada nova linha é um novo comando</li>
<li>Linhas de comentário começam com um <span>#</span></li>
<li>Os comandos são rodeados por ()</li>
</ul>
<p></p>
<p>Quando o OS (shell) analisa um arquivo de texto, a maneira mais direta para identificar o arquivo como um script é fazendo a sua primeira linha ser: #!/bin/bash. Linhas de comentário começam com hashes (#), mas acrescentando o Bang (!) e o shell path depois, forçar o OS a executar o script.</p>
<p></p>
<p>Por exemplo, para criar um shell script para comandar os motores a irem “para a frente”, e com base na tabela acima, devemos tomar um editor de texto e criar o arquivo abaixo (Use o editor que melhor funcione para você Eu estou usando NANO para isso):</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">sudo nano forward.cgi</span></strong></i></span></span></p>
<p class="p1"><span class="s1"> <span style="color: #993300;">#!/bin/bash</span></span></p>
<p class="p1"><span class="s1"> <span style="color: #993300;"> gpio -g write 5 1</span></span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 6 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 13 1</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 19 0</span></p>
<p>.</p>
<p><span>Uma vez que o script é criado, devemos dar-lhe permissão para ser executado:</span></p>
<p><em><span><span> <span style="color: #ff6600;"><strong>sudo chmod 755 forward.cgi</strong></span></span></span></em></p>
<p></p>
<p>Agora, para executar o script:</p>
<p><em><span><span> <strong><span style="color: #ff6600;">sudo ./forward.cgi</span></strong></span></span></em></p>
<p></p>
<p>Foram utilizados LEDs para testar os scripts, os motores reais serão adicionados em uma próxima etapa.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/img_3722.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3722.jpg?w=840&width=300" width="300" class="align-left"/></a></p>
<p>Note que uso .cgi como extensão de arquivo. CGI significa “Common Gateway Interface”. É uma maneira padrão para servidores web interagir com programas executáveis instalados em um servidor que gera páginas web dinamicamente. Tais programas são conhecidos como scripts CGI ou simplesmente CGIs; eles geralmente são escritos em uma linguagem de script, mas podem ser escritos em qualquer linguagem de programação.</p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p>Continuando, a mesma idéia deve ser aplicada para as outras combinações da tabela anterior:</p>
<p> </p>
<p class="p1"><span class="s1"><span><i> <span> <strong><span style="color: #ff6600;">sudo nano stop.cgi</span></strong></span></i></span></span></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 5 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 6 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 13 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 19 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> .</span></p>
<p class="p1"><span class="s1" style="color: #993300;"><i> <span style="color: #ff6600;"><strong>sudo nano reverse.cgi</strong></span></i></span></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 5 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 6 1</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 13 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 19 1</span></p>
<p class="p1"><span style="color: #993300;">.</span></p>
<p class="p1"><span class="s1" style="color: #993300;"><i> <strong><span style="color: #ff6600;">sudo nano left.cgi</span></strong></i></span></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 5 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 6 1</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 13 1</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 19 0</span></p>
<p class="p1"><span style="color: #993300;">.</span></p>
<p class="p1"><span class="s1" style="color: #993300;"><i> <span style="color: #ff6600;"><strong>sudo nano right.cgi</strong></span></i></span></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 5 1</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 6 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 13 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 19 1</span></p>
<p><span style="color: #993300;">.</span></p>
<p><span>Uma vez criados os scripts, você deverá dar-lhes permissão para serem executados, o mesmo que foi feito com forward.cgi</span></p>
<p> </p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">sudo chmod 755 stop.cgi</span></strong></i></span></span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo chmod 755 reverse.cgi</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo chmod 755 left.cgi</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo chmod 755 right.cgi</i></span></strong></p>
<p></p>
<p><span>Agora, execute alguns testes para confirmar que tudo está funcionando:</span></p>
<p> </p>
<p class="p1"><span class="s1"><span><i> </i> <span style="color: #ff6600;">./forward.cgi</span></span></span></p>
<p class="p1"><span class="s1" style="color: #ff6600;"> ./left.cgi</span></p>
<p class="p1"><span class="s1" style="color: #ff6600;"> ./reverse.cgi</span></p>
<p class="p1"><span class="s1" style="color: #ff6600;"> ./right.cgi</span></p>
<p class="p1"><span class="s1" style="color: #ff6600;"> ./stop.cgi</span></p>
<p></p>
<p>Uma boa prática é temos um diretório específico para os programas utilizados e chamar-lo de “bin”. Assim, para guardar os scripts que vamos usar no projeto, deveremos criar um diretório, por exemplo <span>cgi-bin</span> contendo todos os scripts executáveis (ou arquivos binários).</p>
<p></p>
<p>Criemos o diretório “www” sob “var”, onde a nossa página web será localizado e sob ele, o diretório “cgi-bin” com os scripts:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">sudo mkdir /var/www</span></strong></i></span></span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo mkdir /var/www/cgi-bin</i></span></strong></p>
<p class="p1"></p>
<p class="p1">Agora, movamos todos os arquivos para este novo diretório:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">sudo mv /*.sgi /var/www/cgi-bin</span></strong></i></span></span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> cd /var/www/cgi-bin</i></span></strong></p>
<p></p>
<p>Usando o comando <em><span><span>ls</span></span></em>, poderemos ver os arquivos criados:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/fp916tiioo5kk1r-large.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/fp916tiioo5kk1r-large.jpg?w=840&width=300" width="300" class="align-full"/></a></p>
<h4>LIGAR / DESLIGAR UM LED E CONTROLAR A VELOCIDADE DOS MOTORES (OPCIONAL)</h4>
<p>Uma vez que vamos utilizar como H-Bridge, oL293-D para o controle motor, devemos decidir se além da direção, também queremos controlar a velocidade.</p>
<p></p>
<p>Duas possibilidades aqui:</p>
<ul>
<li>Velocidade fixa: A ligar pinos 1 e 9 da ponte (enable) em + 5V (velocidade máxima) ou qualquer outro valor proporcional usando um divisor de tensão com 2 resistores</li>
<li>Pinos 1 e 9 ligados ao Raspberry Pi GPIO.18 (saída PWM)</li>
</ul>
<p></p>
<p>Criaremos um grupo de scripts da mesma maneira que fizemos para definir o controle de direção:</p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo nano nospeed.cgi</i></span></strong></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio pwm 1 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;">.</span></p>
<p class="p1"><span class="s1" style="color: #993300;"><i> <strong><span style="color: #ff6600;"> sudo nano lowspeed.cgi</span></strong></i></span></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio pwm 1 250</span></p>
<p class="p1"><span class="s1" style="color: #993300;">.</span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo nano regularspeed.cgi</i></span></strong></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio pwm 1 512</span></p>
<p class="p1"><span class="s1" style="color: #993300;">.</span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo noano highspeed.cgi</i></span></strong></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio pwm 1 1023</span></p>
<p class="p1"><span class="s1">.</span><br/>Uma vez que os scripts são criados, você deve dar-lhes permissão para serem executados:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;"> sudo chmod 755 nospeed.cgi</span></strong></i></span></span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo chmod 755 lowspeed.cgi</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo chmod 755 regularspeed.cgi</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo chmod 755 highspeed.cgi</i></span></strong></p>
<p></p>
<p><span>Agora, é só executar alguns testes para confirmar que tudo está funcionando:</span></p>
<p> </p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> ./lowspeedcgi</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> ./regularspeed.cgi</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> ./highspeed.cgi</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> ./nospeedcgi</i></span></strong></p>
<p></p>
<p><span>Para testes, conectaremos um LED ao GPIO.18, o que permitirá ver pela intensidade de seu brilho, que o comando está funcionando.</span></p>
<p></p>
<p>Por último, criaremos um script extra para controlar uma saída digital, que será utilizada para ligar ou desligar uma lâmpada, por exemplo. Usaremos o GPIO.10 para isso:</p>
<p> </p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo nano llighton.cgi</i></span></strong></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 10 1</span></p>
<p class="p1"><span class="s1" style="color: #993300;">.</span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo nano llightoff.cgi</i></span></strong></p>
<p class="p1"><span class="s1" style="color: #993300;"> #!/bin/bash</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g write 10 0</span></p>
<p class="p1"><span class="s1" style="color: #993300;">.</span></p>
<p class="p1"><span style="color: #ff6600;"><strong><span class="s1"><i> sudo chmod 755 lighton.cgi</i></span></strong></span></p>
<p class="p1"><span style="color: #ff6600;"><strong><span class="s1"><i> sudo chmod 755 lightoff.cgi</i></span></strong></span></p>
<p> </p>
<p>Uma última coisa antes de passar para outra etapa. Se você reiniciar o RPi, o GPIOs retornarão ao seu estado padrão que é INPUT. Então, temos de alterar o script <span>/etc/rc.local</span> o qual é executado no início de todo boot.</p>
<p>Pouco antes do último comando no script (exit 0), devemos incluir os comandos de definição de modo dos GPIOs:</p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo nano /etc/rc.local</i></span></strong></p>
<p class="p1"><span class="s1" style="color: #993300;"> …</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g mode 5 out</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g mode 6 out</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g mode 13 out</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g mode 19 out</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio -g mode 10 out</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> gpio mode 1 pwm</span></p>
<p class="p1"><span class="s1" style="color: #993300;"> exit 0</span></p>
<p></p>
<p><span>É bom ter o comando de PWM como a ultima linha de comando antes do “exit 0”.</span></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/fqb7m04ioo5l4sc-large.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/fqb7m04ioo5l4sc-large.jpg?w=840&width=400" width="400" class="align-full"/></a></p>
<p></p>
<p>Agora, sempre que que o RPI é iniciado, ele estará pronto para controlar as saídas projetadas.</p>
<p></p>
<p>Aproveite e faça o reboot do sistema agora:</p>
<p><strong><span style="color: #ff6600;"><em> sudo reboot</em></span></strong></p>
<h4>INSTALANDO O WEBSERVER</h4>
<p>Instalaremos o lighttpd que é um servidor web muito leve e rápido (pode ser usado em vez do Apache por exemplo). Conforme descrito em sua <a href="http://redmine.lighttpd.net/projects/lighttpd/wiki" target="_blank">wikipage</a> “, Lighttpd é um servidor web seguro, rápido e muito flexível, otimizado para ambientes de alto desempenho. Ele tem um baixo consumo de memória em comparação com outros servidores web, além de cuidar de não carregar demasiado a CPU.</p>
<p></p>
<p>Instalemos o Lighttpd e seus componentes:</p>
<p> </p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo apt-get -y install lighttpd</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo lighttpd-enable-mod cgi</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo lighttpd-enable-mod fastcgi</i></span></strong></p>
<p></p>
<p><span>Por default, Lighttpd procurará uma página <span>index.html</span> no diretório: <span>/ var / www / html</span>. Vamos alterar isso, de modo que o index.html fique armazenado diretamente na pasta: <span>/ var / www</span>.</span></p>
<p></p>
<p><span>Para isso, é preciso editar o arquivo de configuração do Lighttpd:</span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo nano /etc/lighttpd/lighttpd.conf</i></span></strong></p>
<p></p>
<p>alterar:</p>
<p></p>
<p><span class="s1"> <span style="color: #993300;"> server.document-root =“/var/www/html”</span></span></p>
<p></p>
<p>para:</p>
<p><span> <span style="color: #993300;"> server.document-root =“/var/www”</span></span></p>
<p></p>
<p><span>A fim de que esta alteração tenha efeito, é necessário parar e reiniciar o servidor web:</span></p>
<p> </p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo /etc/init.d/lighttpd stop</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo /etc/init.d/lighttpd start</i></span></strong></p>
<p></p>
<p><span>Neste ponto, o servidor web está em execução e se a página index.html está localizado em / var / www, podemos acessa-la a partir de qualquer navegador, apenas digitando o endereço IP RPi.</span></p>
<p></p>
<p>Criaremos uma página simples para efeito de testes.</p>
<p></p>
<p>Primeiro, criemos um subdiretório para armazenar as imagens da pagina:</p>
<p><span>mkdir /var/www/images</span></p>
<p></p>
<p>(Note que para o teste, já me enviei um arquivo .png para o diretório (/images/robot52.png):</p>
<p><span>cd / var / www</span></p>
<p><span>sudo index.html nano</span></p>
<p></p>
<p><html></p>
<p><head></p>
<p></head></p>
<p><style></p>
<p>body</p>
<p>{</p>
<p>background-color: lightyellow}</p>
<p>h1 {color:blue}</p>
<p></style></p>
<p></p>
<p><body></p>
<p><div style="text-align:center"></p>
<p><h1>MJRoBot RPi Web Robot Control</h1> <br><br> <img src="/images/robot52.png"></p>
<p></body> <</p>
<p>/html></p>
<pre class="p1"></pre>
<p></p>
<p>Depois de terminar a edição da página, guardar-la e alterar as permissões:</p>
<p> <em><strong><span style="color: #ff6600;"> sudo chmod 755 index.html</span></strong></em></p>
<p></p>
<p>Agora, abra o navegador e digite o endereço IP Raspberry Pi, por exemplo no meu caso: 10.0.0.31</p>
<p></p>
<p>O resultado final pode ser visto abaixo:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/f7m7eebioo5l527-large.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/f7m7eebioo5l527-large.jpg?w=840&width=400" width="400" class="align-full"/></a></p>
<h4>CRIANDO UMA PÁGINA HTML PARA CONTROLAR O ROBÔ</h4>
<p></p>
<p>Vamos pensar em um projeto simples para a nossa página. Que comandos podemos ter?</p>
<ul>
<li>Dois botões para ligar e desligar as luzes ==> irão trabalhar com os scripts: lighton.cgi e lighoff.cgi</li>
<li>Cinco botões para controle de direção do motor ==> irão trabalhar com os scripts: forward.cgi, stop.cgi, left.cgi, right.cgi e reverse.cgi</li>
<li>Quatro botões para controle de velocidade do motor ==> irão trabalhar com os escripts: nospeed.cgi, lowspeed.cgi, regularspeed.cgi e highspeed.cgi</li>
</ul>
<p></p>
<p>Usando o arquivo em HTML index.html que acabamos de criar na última etapa, incluir emos botões que por sua vez chamarão funções para execução dos respectivos scripts.</p>
<p></p>
<p>Por exemplo, vamos criar um botão para acender o LED (GPIO.10):</p>
<p></p>
<p>button</p>
<p>{</p>
<p> color: blue;</p>
<p> background:lightgrey;</p>
<p> border: 1px solid #000;</p>
<p> border-radius: 8px;</p>
<p> position: center;</p>
<p>}</p>
<p></p>
<p><button style="height: 50.0px;width: 100.0px;"><img src="/images/lighton.png" style="height: 40.0px;"></button></p>
<p></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/botao.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/botao.png?w=840&width=200" width="200" class="align-full"/></a></p>
<p></p>
<p>O código HTML acima criará um botão redondo com uma “lâmpada iluminada”.</p>
<p></p>
<p>Quando o botão é pressionado, devido o comando “onclick = lighton ()”, a função “lighton()” é chamada:</p>
<p></p>
<p>function lighton()</p>
<p>{</p>
<p>xmlhttp.open("GET","cgi-bin/lighton.cgi",true);</p>
<p>xmlhttp.send();</p>
<p>}</p>
<p></p>
<p>E uma vez que a função lighton() é chamado, o script lighton.cgi é executado e “voilá”, o LED acenderá.</p>
<p>O mesmo procedimento deve ser utilizado para todos os demais botões. Há alguns outros comandos HTML que serão utilizados para organizar o look &fill da pagina.</p>
<p></p>
<p><img class="alignnone size-full wp-image-4950" src="https://mjrobot.files.wordpress.com/2016/06/f56i7p0ioo5l6um-large.jpg?w=840" alt="F56I7P0IOO5L6UM.LARGE"/></p>
<p></p>
<p>Abaixo o arquivo fonte HTML pode ser visto (testar a página com a configuração de LEDs utilizados nas etapas anteriores):</p>
<p><a href="https://www.dropbox.com/s/5ch38wv95lndtr3/index_Part1.html?dl=0" target="_blank">Link para a pagina HTML</a></p>
<p></p>
<h4>MONTAGEM DO CORPO DO ROBÔ</h4>
<p>A primeira coisa é encontrar uma plataforma. Eu decidi aproveitar um kit 4WD com 4 motores de corrente contínua. Percebendo que o 4WD não é fácil de controlar (para fazer curvas) e uma vez que a idéia aqui não é analise de mobilidade, eu montei o robô completo, mas para o teste real eu só usarei as rodas traseiras, adicionando um “Coster” na parte frontal (sobras de um desodorante do tipo “rolon”).</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3552/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3552.jpg?w=556&h=417&crop=1&width=400" width="400" class="align-full"/></a></div>
</div>
<div class="gallery-group images-2"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3554/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3554.jpg?w=276&h=206&crop=1&width=400" width="400" class="align-full"/></a></div>
<div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3555/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3555.jpg?w=276&h=207&crop=1&width=400" width="400" class="align-full"/></a></div>
</div>
</div>
</div>
<p> </p>
<p>Depois que o corpo e os motores estão no lugar, é hora de incluir um protoboard, faça as conexões do motor e testá-lo. Utilize a bateria externa para testar cada um dos motores.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/img_3563.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3563.jpg?w=840&width=400" width="400" class="align-full"/></a></p>
<p>Os motores irão ser controlado por uma ponte-H L293-D conforme mostrado no diagrama abaixo:</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/l293d_conextions/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/l293d_conextions.png?w=607&h=300&crop=1&width=400" width="400" class="align-right"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-small"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3565/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3565.jpg?w=225&h=300&crop=1&width=225" width="225" class="align-left"/></a></div>
</div>
</div>
</div>
<p>Neste ponto, você também pode fazer testes, controlando os motores usando + 5V e GND nas entradas da ponte, simulando as GPIOs do RPI.</p>
<h4>.</h4>
<h4>INSTALAÇÃO DO RPI</h4>
<p>Uma vez que tudo está funcionando corretamente, é hora de adicionar o Raspberry Pi. O circuito completo é mostrado abaixo:</p>
<p><img class="alignnone size-full wp-image-4991 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/06/circuit-motors-only.png?w=840" alt="Circuit Motors only"/></p>
<p>Instalar a bateria RPI 5V entre os motores com menor chassis nível. A RPI está no topo.</p>
<p>Faça todas as conexões de cabos antes de ligar o RPI.</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3723/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3723.jpg?w=532&h=399&crop=1&width=300" width="300" class="align-full"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3724/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3724.jpg?w=300&h=399&crop=1&width=300" width="300" class="align-full"/></a></div>
</div>
</div>
<div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3725/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3725.jpg?w=836&h=1115&crop=1&width=300" width="300" class="align-full"/></a></div>
</div>
</div>
</div>
<p> </p>
<p>Se todas as etapas anteriores foram OK, você poderá controlar o robô, usando o endereço IP RPi.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/img_3726.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3726.jpg?w=840&width=400" width="400" class="align-full"/></a></p>
<p>Abra seu WebBrowser favorito e viagem segura!</p>
<p>Abaixo, um vídeo onde o robô é testado usando a página da Web:</p>
<div class="jetpack-video-wrapper"><p class="p1"></p>
<p class="p1"><span class="s1"><a href="https://youtu.be/_NAPmwNwUJc">https://youtu.be/_NAPmwNwUJc</a></span></p>
</div>
<h3>Segunda Parte: Streaming de video e controle remoto (Pan / Tilt) da câmera pela internet</h3>
<h3><span>Como discutido na introdução, o robô é quase uma desculpa para desenvolver um projeto de Internet das coisas. o que fizemos aqui é controlar os GPIOs do RPI através da internet.a A partir daí, podemos controlar praticamente tudo!</span></h3>
<p></p>
<p>Nesta segunda parte, exploraremos a PiCam, descobriremos como fazer streaming de vídeo e também a forma de controlar a posição da câmera usando servos. Controlar uma câmera através da internet pode ter várias utilidades, inclusive para uso em segurança.</p>
<p></p>
<p>O objetivo final, será unir as duas partes do projeto, criando um robô que pode ser não só ser controlado pela internet, mas também transmitir streaming de vídeo.</p>
<p> </p>
<p>O diagrama de blocos abaixo mostra a idéia da segunda parte do projeto.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/webcam-ctrl.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/webcam-ctrl.png?w=840&width=400" width="400" class="align-full"/></a></p>
<p>O RPI será programado como um servidor web e irá receber comandos de uma página HTML. Esses comandos irão controlar os GPIOs do RPi, posicionando a PiCam através dos servomotores (Pan / horizontal e Tilt/ vertical).</p>
<h4>LISTA DE MATERIAIS</h4>
<p>A lista de materiais anterior, acrescentaremos a PiCam e dois mini-servos de 180 graus. Será necessário também um regulador de voltagen de 6V (7806), para se poder usar a mesma bateria de 9V já instalada para alimentação dos motores.</p>
<h4>STREAMING VÍDEO</h4>
<p>Instalaremos o streamer de vídeo PiCam baseado no tutorial:</p>
<p><a href="https://miguelmota.com/blog/raspberry-pi-camera-board-video-streaming/" target="_blank">Raspberry Pi camera board video streaming </a>, desenvolvido por Miguel Mota (atualização de 19 de janeiro de 2014).</p>
<p></p>
<p>Primeiro, vamos atualizar o sistema operacional:</p>
<p class="p1"><span class="s1"><span><i> <span style="color: #ff6600;"><strong>sudo apt-get update</strong></span></i></span></span></p>
<p class="p1"><span style="color: #ff6600;"><strong><span class="s1"><i> sudo apt-get upgrade</i></span></strong></span></p>
<p></p>
<p><span>Instalar a versão dev de libjpeg:</span></p>
<p class="p1"><span class="s1"><span><i> <span><strong><span style="color: #ff6600;">sudo apt-get install libjpeg62-turbo-dev</span></strong> </span></i></span></span><span>Nota: libjpeg62-dev é obsoleto e foi substituído por este)</span></p>
<p></p>
<p>Instalar cmake:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">sudo apt-get install cmake</span></strong></i></span></span></p>
<p></p>
<p>Baixar mjpg-streamer com o plugin raspicam:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">git clone </span></strong></i></span><a href="https://github.com/jacksonliam/mjpg-streamer.git"><span class="s2"><span><i>https://github.com/jacksonliam/mjpg-streamer.git</i></span></span></a><strong><span style="color: #ff6600;"><i>~/mjpg-streamer</i></span></strong></span></p>
<p></p>
<p>Alterar o diretório:</p>
<p class="p1"><span class="s1"><span><i> <span> <strong><span style="color: #ff6600;">cd ~/mjpg-streamer/mjpg-streamer-experimental</span></strong></span></i></span></span></p>
<p></p>
<p><span>Compilar:</span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> make clean all</i></span></strong></p>
<p></p>
<p>Substituir o velho jpg-streamer:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">sudo rm -rf /opt/mjpg-streamer</span></strong></i></span></span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo mv ~/mjpg-streamer/mjpg-streamer-experimental /opt/mjpg-streamer</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> sudo rm -rf ~/mjpg-streamer</i></span></strong></p>
<p></p>
<p><span>Iniciar a transmissão:</span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i “input_raspicam.so -fps 15 -q 50 -x 640 -y 480” -o “output_http.so -p 9000 -w /opt/mjpg-streamer/www” &</i></span></strong></p>
<p></p>
<p>A câmera deverá estar funcionando. Vá para o seu navegador e digite:</p>
<p></p>
<p><span> http: // <em><span>O seu endereço IP</span></em>: 9000 / stream.html</span></p>
<p></p>
<p>A página de teste como a de abaixo deverá aparecer (com a imagem capturada por sua camera).</p>
<p><img class="alignnone size-full wp-image-5086" src="https://mjrobot.files.wordpress.com/2016/06/video-streamer-test.png?w=840" alt="Video Streamer test"/></p>
<p></p>
<p>Note que se você quiser alterar a porta de comunicação, troque o parâmetro “9000” na linha de comando que voce entrou no monitor do RPI,por um que melhor funcione para você. Observe que estamos trabalhando com 15 quadros por segundo (fps) e uma resolução de 640×480. Você também pode alterar esses parâmetros na linha de comando.</p>
<p>Você deverá voltar a entrar com a linha de comando acima para iniciar a transmissão de toda a vez que seu sistema seja reiniciado (reboot), a menos que você inclua o comando no script <span>/etc/rc.local</span>, como mostrado abaixo:</p>
<p> </p>
<p class="p1"><span class="s1"><span><i> <span> <strong><span style="color: #ff6600;">sudo nano /etc/rc.local</span></strong></span></i></span></span></p>
<p class="p2"><span class="s1"><i> …</i></span></p>
<p class="p2"><span class="s1"><i> <span style="color: #993300;">LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i “input_raspicam.so -fps 15 -q 50 -x 640 -y 480” -o “output_http.so -p 9000 -w /opt/mjpg-streamer/www” &</span></i></span></p>
<p class="p2"><span class="s1" style="color: #993300;"><i>…</i></span></p>
<p>Considerando que o webserver já esteja instalado, necessitamos introduzir a linha abaixo para que o streaming the video apareça em nossa página:</p>
<p></p>
<p><iframe src="http://Your IP Adress:9000/javascript_simple.html" frameborder="0" align="middle" width="640" height="480" align="middle" scrolling="no">$</p>
<p></p>
<p>Abaixo, podemos observar a simples página em HTML com a linha acima incluída:</p>
<p><html></p>
<p><head></p>
<p></head></p>
<p><style></p>
<p>body {</p>
<p>background-color: lightyellow}</p>
<p>h1 {color:blue}</p>
<p></style></p>
<p><body></p>
<p><div style="text-align:center"> <h1> MJRoBot RPi Web Robot Control <img style="height: 100px"src="/images/robot52.png"> </h1></p>
<p><br><br></p>
<p><iframe src="http://10.0.1.31:9000/javascript_simple.html" frameborder="0" align="middle" width="640" height="480" align="middle" scrolling="no">$</p>
<p></body></p>
<p></html></p>
<p></p>
<p>Entrando com o IP do RPi no navegador, chegamos ao resultado abaixo:</p>
<p class="p1"><img class="alignnone size-full wp-image-5279" src="https://mjrobot.files.wordpress.com/2016/06/mjrobot-video-streamer-test.png?w=840" alt="MJRoBot Video Streamer test"/></p>
<h4 class="p2"></h4>
<h4 class="p2"><span>INSTALAÇÃO DA BIBLIOTECA SERVOBLASTER</span></h4>
<p>Uma grande biblioteca a ser usada para controlar os servos é a ServoBlaster</p>
<p>Este é um software específico para o Raspberry Pi, que fornece uma interface para controlar múltiplos servos através dos pinos GPIO. Você controla as posições dos servos enviando comandos que variam a largura de pulso de uma saída. O GPIO manterá a largura do pulso até que você envíe um novo comando alterando o valor anterior.</p>
<p>Por default, ServoBlaster está configurado para controlar 8 servos, mas você pode configurá-lo para até 21. Servos normalmente precisam de um pulso ativo de algo entre 0,5 ms e 2,5 ms, onde a largura do pulso controla a posição do servo. O pulso deve ser repetido aproximadamente a cada 20 ms, embora essa frequência não seja crítica. A largura de pulso sim, é fundamental pois é ela é traduzida diretamente para a posição de servo.</p>
<p>Além de controlar servos, ServoBlaster pode ser configurado para gerar larguras de pulsos entre 0 e 100% (duty-cycle), tornando-o adequado para controlar o brilho de até 21 LEDs, por exemplo.</p>
<p>O ServoBlaster cria um device file <span>/dev/servoblaster</span>, no qual você poderá enviar comandos. O formato do comando é:</p>
<p></p>
<p>[Servo-número] = [servo-position]</p>
<p>(Ex .: <strong><span style="color: #ff6600;"><em>echo P1-11 = 80% >/dev/servoblaster</em></span></strong>)</p>
<p>ou</p>
<p>P [header] – [pin] = [servo-position]</p>
<p>(Ex: <strong><span style="color: #ff6600;">echo P0 = 80% >/dev/servoblaster)</span></strong></p>
<p>Primeiramente, clonemos projeto Richardghirst do GitHub:</p>
<p class="p1"><span class="s1"><span><i> <span> <strong><span style="color: #ff6600;">cd /</span></strong></span></i></span></span></p>
<p class="p2"><strong><span class="s2" style="color: #ff6600;"><i> sudo git clone </i><a href="https://github.com/richardghirst/PiBits"><span class="s3" style="color: #ff6600;"><i>https://github.com/richardghirst/PiBits</i></span></a></span></strong></p>
<p></p>
<p><span>Alterar diretório:</span></p>
<p> </p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">cd PiBits</span></strong></i></span></span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> cd ServoBlaster</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> cd user</i></span></strong></p>
<p></p>
<p>Liste o conteúdo e verificar se o diretório contém o arquivo “servod.c”</p>
<p><em><span><span> <strong><span style="color: #ff6600;">ls</span></strong></span></span></em></p>
<p></p>
<p>Compilar e instalar o arquivo servod.c :</p>
<p class="p1"><span class="s1"><span><i> </i></span><strong><span style="color: #ff6600;"><em>sudo make servod</em></span></strong></span></p>
<p class="p1"><strong><span style="color: #ff6600;"><em><span class="s1"> sudo make install</span></em></span></strong></p>
<p></p>
<p><span>Neste momento, o programa servod será instalado.</span></p>
<p><span>Alterar as permissões e executar o programa para poder testar-lo:</span></p>
<p><span><em><span> <strong><span style="color: #ff6600;">sudo chmod 755 servod</span></strong></span></em></span></p>
<p><span><em><span> <strong><span style="color: #ff6600;">sudo ./servod</span></strong></span></em></span></p>
<p></p>
<p>Se tudo estiver OK, você deverá ver no monitor o mapeamento dos servos. Temos por default 8 servos configurados, mas por exemplo no caso do controle da camera, só precisaremos de 2, por isso deveremos restringir os pinos a ser em utilizados. Consideremos apenas:</p>
<ul>
<li>GPIO.17 (P1-11) que será usado para TILT (controle vertical)</li>
<li>GPIO.23 (P1-16) que será usado para PAN (controle horizontal)</li>
</ul>
<p></p>
<p>Para se definir os pinos que serão configurados, entrar com os parâmetros abaixo:</p>
<p> <em><strong><span style="color: #ff6600;">sudo ./servod –p1pins = 11,16</span></strong></em></p>
<p></p>
<p>Uma vez executado o comando acima, o monitor deverá agora mostrar em sua parte inferior:</p>
<p></p>
<p>Using P1 pins: 11,16</p>
<p>Servo mapping:</p>
<p>0 on P1-11 GPIO-17</p>
<p>1 on P1-16 GPIO-23</p>
<p><br/> Observe também que se você reiniciar o RPI, a configuração será perdida, por isso é importante incluir o último comando no /etc/rc.local</p>
<p></p>
<p><strong><span style="color: #ff6600;"><em> sudo nano /etc/rc.local </em></span></strong></p>
<p><span style="color: #993300;"> …</span></p>
<p class="p1"><span class="s1" style="color: #993300;"><i> cd /PiBits/ServoBlaster/user</i></span></p>
<p class="p1"><span class="s1" style="color: #993300;"><i> sudo ./servod –p1pins=11,16</i></span></p>
<p class="p1"><span class="s1" style="color: #993300;"><i> cd</i></span></p>
<p><span style="color: #993300;"> …</span></p>
<p>Também é importante a mudança no script abaixo:</p>
<p> </p>
<p class="p1"><span class="s1"><span><i> <span style="color: #ff6600;"><strong>sudo nano /etc/init.d/servoblaster</strong></span></i></span></span></p>
<p class="p2"><span class="s1"><i> <span style="color: #993300;">…</span></i></span></p>
<p class="p2"><span class="s1" style="color: #993300;"><i> case “$1” in<br/> start)</i></span></p>
<p class="p2"><span class="s1" style="color: #993300;"><i> /usr/local/sbin/servod $OPTS >/dev/null</i></span></p>
<p class="p2"><span class="s1">change to:</span></p>
<p class="p3"><span><span class="s1"><i> <span style="color: #993300;"> /usr/local/sbin/servod </span></i></span><span style="color: #993300;"><span class="s2"><i>–p1pins=11,16</i></span><span class="s1"><i> $OPTS >/dev/null</i></span></span></span></p>
<p></p>
<p>Agora reinicie o sistema, para que as alterações podem ser permanentes</p>
<p><strong><span style="color: #ff6600;"><em> sudo reboot</em></span></strong></p>
<p></p>
<p>É isso aí. Servo Blaster está instalado. Note que a partir deste momento, ServoBlaster irá reconhecer apenas dois servos:</p>
<ul>
<li>servo 0 ==> p1-11</li>
<li>servo 1 ==> p1-16</li>
</ul>
<p></p>
<p>O comando echo pode ser executado em qualquer um dos formatos acima, com o mesmo resultado:</p>
<p> </p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;">echo P1-11=40% >/dev/servoblaster</span></strong></i></span></span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> echo P1-16=60% >/dev/servoblaster</i></span></strong></p>
<p class="p1"><span class="s1">or</span></p>
<p class="p1"><span class="s1"><span><i> <span style="color: #ff6600;"><strong>echo 0=40% >/dev/servoblaster</strong></span></i></span></span></p>
<p class="p1"><span style="color: #ff6600;"><strong><span class="s1"><i> echo 1=60% >/dev/servoblaster</i></span></strong></span></p>
<h4>MONTAGEM DO MECANISMO DE PAN/TILT</h4>
<p>Existem vários mecanismos Pan / Tilt no mercado, mas decidi por montar uma forma muito simples, só amarrando os servos e a PiCam como você pode ver nas fotos abaixo:</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-3"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3745/"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3745.jpg?w=307&h=230&crop=1" width="307" height="230" title="IMG_3745" alt="IMG_3745"/></a></div>
<div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3746/"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3746.jpg?w=307&h=231&crop=1" width="307" height="231" title="IMG_3746" alt="IMG_3746"/></a></div>
<div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3747/"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3747.jpg?w=307&h=231&crop=1" width="307" height="231" title="IMG_3747" alt="IMG_3747"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3748/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3748.jpg?w=525&h=700&crop=1&width=300" width="300" class="align-full"/></a></div>
</div>
</div>
</div>
<h4>INSTALAR O SERVOS AO RPI</h4>
<p><img class="alignnone size-full wp-image-5211" src="https://mjrobot.files.wordpress.com/2016/06/rpiservos-circuit-diagram.png?w=840" alt="RPi&amp;Servos circuit diagram"/></p>
<ul>
<li>Ligue o cabo de dados dos servos ao RPI, como mostrado acima.</li>
<li>Conecte o + V de ambos os servos em uma fonte de tensão separada a do RPI (claro, os GNDs devem estar interligados). Uma vez que você irá instalar o mecanismo de Pan / Tilt no robô, você poderá utilizar a mesma bateria (9V) que foi usado com os motores de corrente contínua. Neste caso, um regulador de tensão de 6V será necessário.</li>
</ul>
<p></p>
<p>Para testar os servos, use o comando”echo” do Servoblaster . Você poderá usar tanto valores de ângulo quanto de percentual. Teste a melhor faixa para seu mecanismo de Pan / Tilt:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/rpiservos-block-diagram4.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/rpiservos-block-diagram4.png?w=840&width=400" width="400" class="align-full"/></a></p>
<p>TILT Servo:</p>
<p class="p1"><span class="s1"><strong><span style="color: #ff6600;"><i> echo P1-11=20% >/dev/servoblaster </i>(</span></strong>looking down)</span></p>
<p class="p2"><span class="s1"><span style="color: #ff6600;"><strong><i> echo P1-11=60% >/dev/servoblaster </i></strong></span>(looking front)</span></p>
<p class="p2"><span class="s1"><span><i><span style="color: #ff6600;"><strong> echo P1-11=90% >/dev/servoblaster</strong></span> </i></span>(looking up)</span></p>
<p></p>
<p><span>PAN Servo:</span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> echo P1-16=30% >/dev/servoblaster</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> echo P1-16=62% >/dev/servoblaster</i></span></strong></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> echo P1-16=90% >/dev/servoblaster</i></span></strong></p>
<p></p>
<p><span>Podemos facilmente scripts para controlar a posição dos servos. </span>Por exemplo, para criar um shell script para posicionar a câmera “olhando para frente”, baseado nos valores que você encontrou, devemos criar o arquivo abaixo:</p>
<p class="p1"><span class="s1"><span><i> <strong><span style="color: #ff6600;"> sudo nano cam_view_front.cgi</span></strong></i></span></span></p>
<p class="p2"><span class="s1" style="color: #993300;"><i> #!/bin/bash</i></span></p>
<p class="p2"><span class="s1" style="color: #993300;"><i> echo P1-11=60% >/dev/servoblaster<br/> echo P1-16=62% >/dev/servoblaster</i></span></p>
<p class="p1"><span class="s1">.</span></p>
<p><span>Uma vez que o script é criado, devemos dar-lhe permissão para ser executado:</span></p>
<p class="p1"><span class="s1"><span><i> <span style="color: #ff6600;"><strong>sudo chmod 755 cam_view_front.cgi</strong></span></i></span></span></p>
<p></p>
<p><span>Agora, executar o script:</span></p>
<p class="p1"><strong><span class="s1" style="color: #ff6600;"><i> ./cam_view_front.cgi</i></span></strong></p>
<p></p>
<p><span>Movimente a câmera para qualquer posição usando o comando echo e depois executar o novo script. Você vai ver que a câmera voltará automaticamente à sua posição “vista frontal”.</span></p>
<p></p>
<p>Continuando, a mesma idéia deve ser aplicada para as outras possíveis posições de câmera.</p>
<p>Para gerar minha página, optei por criar 5 posições intermediárias para TILT e 5 posições intermediárias para PAN. Você também pode optar por usar “sliders” para uma mudança de posição mais contínua. Você decide.</p>
<p>Usando o mesmo princípio como o descrito para o script “cam_view_front.cgi”, vamos criar 10 novos scripts:</p>
<ol>
<li>leftpan.cgi ==> 90%</li>
<li>leftcenterpan.cgi ==> 76%</li>
<li>centerpan.cgi ==> 62%</li>
<li>rightcenterpan.cgi ==> 46%</li>
<li>rightpan.cgi ==> 30%</li>
<li>downtilt.cgi ==> 20%</li>
<li>downcentertilt.cgi ==> 40%</li>
<li>centertilt.cgi ==> 60%</li>
<li>upcentertilt.cgi ==> 75%</li>
<li>uptilt.cgi ==> 90%</li>
</ol>
<h4>CRIANDO UMA PÁGINA HTML PARA CONTROLAR A CÂMERA</h4>
<p>Usando o index.html que criamos para o streaming da camera, vamos incluir os 10 botões que chamam funções para executar os scripts criados anteriormente.</p>
<p> </p>
<p><img class="alignnone size-full wp-image-5286" src="https://mjrobot.files.wordpress.com/2016/06/picamwebpagectrl.png?w=840" alt="PiCamWebPageCtrl"/></p>
<p>Abaixo, o código HTML completo para a criação da página:</p>
<p><a href="https://www.dropbox.com/s/wjfr0lypzz9tvzm/index_Part2.html?dl=0" target="_blank">Codigo HTML para pagina index.html</a></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/06/img_3754.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3754.jpg?w=840&width=400" width="400" class="align-full"/></a></p>
<h4>INTEGRANDO A CÂMARA E OS SERVOS AO ROBÔ.</h4>
<p>Agora que temos o nosso RPI streaming vídeo e podendo posicionar a câmera via internet, vamos integrar esta segunda parte do projeto ao robô que foi criado na primeira parte.</p>
<p>O diagrama de blocos do início deste post, mostra como o projeto pode ser integrado e o circuito abaixo mostrar como fazer as conexões:</p>
<p><img class="alignnone size-full wp-image-5302" src="https://mjrobot.files.wordpress.com/2016/06/full-circuit.png?w=840" alt="full circuit"/></p>
<p>Em seguida, tomemos a página web desenvolvida na segunda parte e adicionemos a parte de botões e funções criadas na parte 1 para o controle dos motores.</p>
<p><a href="https://www.dropbox.com/s/m95wibmiah66sq0/index.html?dl=0" target="_blank">Link para página HTML final</a></p>
<h4><img class="alignnone size-full wp-image-5314" src="https://mjrobot.files.wordpress.com/2016/06/final-robot-ctrl-webpage2.png?w=840" alt="Final Robot ctrl webpage2"/></h4>
<h4>O ROBÔ COMPLETO TOMA VIDA!</h4>
<p>O último passo é a integração do mecanismo PAN/TILT a base do robô:</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3577/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3577.jpg?w=556&h=417&crop=1&width=400" width="400" class="align-full"/></a></div>
</div>
<div class="gallery-group images-2"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3598/"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3598.jpg?w=276&h=206&crop=1" width="276" height="206" title="IMG_3598" alt="IMG_3598"/></a></div>
<div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3599/"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3599.jpg?w=276&h=207&crop=1" width="276" height="207" title="IMG_3599" alt="IMG_3599"/></a></div>
</div>
</div>
<div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/06/01/controlando-um-raspberry-pi-robo-pela-internet/img_3578/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/06/img_3578.jpg?w=836&h=627&crop=1&width=400" width="400" class="align-full"/></a></div>
</div>
</div>
</div>
<p>O vídeo abaixo explica como funciona o robô completo:</p>
<div class="jetpack-video-wrapper"><p class="p1"><span class="s1"><a href="https://youtu.be/P7dZ7jJV2w4">https://youtu.be/P7dZ7jJV2w4</a></span></p>
</div>
<h4>CONCLUÍNDO….</h4>
<p>That’s all folks!</p>
<p>Como sempre, espero que este projeto ajude outras pessoas a encontrar seu caminho no apaixonante mundo da eletrônica e dos robôs!</p>
<p>Um abraço e até o próximo post!</p>
<p>Obrigado</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599620?profile=original" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599620?profile=RESIZE_320x320" width="300" class="align-full"/></a></p>Rex, "um robô que nunca perde a linha!" recebe prêmio no ROBOTICS CONTEST 2016tag:labdegaragem.com,2016-05-25:6223006:BlogPost:5368202016-05-25T00:00:00.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p></p>
<p></p>
<h1 class="entry-title"><img alt="Robotics 2016 contest" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" src="https://mjrobot.files.wordpress.com/2016/05/robotics-2016-contest.png?w=1200&h=0&crop=1" width="1200"></img></h1>
<p></p>
<p></p>
<div class="entry-content"><p>Amigos garagistas, gostaria de dividir com vocês uma notícia que me deixou muito feliz. Meu tutorial <a href="http://labdegaragem.com/profiles/blogs/tutorial-rob-seguidor-de-linha-com-controle-pid-e-ajustes-por" target="_self">Robô seguidor de linha com controle PID e ajustes por aplicativo Android</a>, publicado aqui no Garagem em abril, acaba de ganhar o segundo prêmio na competição de…</p>
</div>
<p></p>
<p></p>
<h1 class="entry-title"><img width="1200" src="https://mjrobot.files.wordpress.com/2016/05/robotics-2016-contest.png?w=1200&h=0&crop=1" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="Robotics 2016 contest"/></h1>
<p></p>
<p></p>
<div class="entry-content"><p>Amigos garagistas, gostaria de dividir com vocês uma notícia que me deixou muito feliz. Meu tutorial <a href="http://labdegaragem.com/profiles/blogs/tutorial-rob-seguidor-de-linha-com-controle-pid-e-ajustes-por" target="_self">Robô seguidor de linha com controle PID e ajustes por aplicativo Android</a>, publicado aqui no Garagem em abril, acaba de ganhar o segundo prêmio na competição de robótica 2016 do site<em> <a href="http://instructables.com/">Instructables.com</a> em parceria com a <a href="http://www.nationalroboticsweek.org/About" target="_blank">National Robotics Week</a>. </em>Além de ser uma honra, esse prêmio me deixa muito feliz, pois mostra que estou no caminho certo ao tentar descobrir formas lúdicas e prazeirosas de aprender e ensinar robótica, IoT e eletrônica!</p>
<p>O Rex competiu com projetos incríveis, os quais podem ser vistos em detalhes no link:</p>
<p><a href="http://www.instructables.com/contest/robotics2016/" target="_blank">ROBOTICS CONTEST 2016 – Winners</a></p>
<p><img class="alignnone size-full wp-image-4467 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/05/rex-the-winner2.jpg?w=840" alt="Rex the winner2"/></p>
<p>Obrigado pela força e pelos votos! E vamos “pa’delante!”</p>
<p>Saludos</p>
<p>Marcelo</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596529?profile=original" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979596529?profile=RESIZE_320x320" width="300" class="align-center"/></a></p>
</div>Tutorial: “Raqueando” o carrinho de controle remototag:labdegaragem.com,2016-05-08:6223006:BlogPost:5331642016-05-08T22:06:14.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p></p>
<p>Neste projeto, vamos desarmar um carrinho de controle remoto, substituindo sua eletrônica por um microprocessador Arduino controlado por dispositivo Android</p>
<div class="post-thumbnail"><img alt="Version 2" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" src="https://mjrobot.files.wordpress.com/2016/05/img_24731.jpg?w=1200&h=0&crop=1" width="1200"></img></div>
<div class="entry-content"><p>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…</p>
</div>
<p></p>
<p>Neste projeto, vamos desarmar um carrinho de controle remoto, substituindo sua eletrônica por um microprocessador Arduino controlado por dispositivo Android</p>
<div class="post-thumbnail"><img width="1200" src="https://mjrobot.files.wordpress.com/2016/05/img_24731.jpg?w=1200&h=0&crop=1" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="Version 2"/></div>
<div class="entry-content"><p>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 ;-) vamos desmontar um desses, “raqueando” suas principais partes e substituindo a eletrônica embarcada original por um microcontrolador tipo Arduino facilmente comandado a distância por um dispositivo Android. Com isso, ficará muito fácil adicionar ao carrinho novas funcionalidades, sensores, etc. É uma forma muito barata de se construir um robô para uso didático.</p>
<p>O vídeo abaixo, mostra como ficará o projeto final:</p>
<p><a href="https://youtu.be/kUoYfEG1aN4" target="_blank">O MJRoBot Autobot em ação</a></p>
<h4> .</h4>
<h4>CONHECENDO O CARRINHO</h4>
<p><a href="https://mjrobot.files.wordpress.com/2016/05/img_24301.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/img_24301.jpg?w=840&width=350" width="350" class="align-left"/></a></p>
<p>O primeiro passo será desarmar o carrinho para se ter uma idéia de como ele funciona, o que se aproveitará e o que se deve ser adicionado:</p>
<p>Na parte inferior da carcaça, estão os os dois motores (frontal e traseiro), o compartimento da bateria (recarregável, 5V) e o modulo eletrônico. Na parte superior da </p>
<img src="https://mjrobot.files.wordpress.com/2016/05/img_2450.jpg?w=416&h=555&crop=1&width=300" width="323" class="align-right" height="431"/><br />
<p>carcaça, está a antena (placa de cobre conectada a um cabo negro) e os 4 LEDs que funcionam como os faróis dianteiros e traseiros.</p>
<p>Cada LED está conectado separadamente por um par de fios.</p>
</div>
<div class="entry-content"></div>
<div class="entry-content">Com esse arranjo, se pode:</div>
<div class="entry-content"><ul>
<li>Acender os faróis (acender os dois LEDs frontais)</li>
</ul>
<a href="https://mjrobot.files.wordpress.com/2016/05/img_2446.jpg?w=416&h=555&crop=1&width=350" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/img_2446.jpg?w=416&h=555&crop=1&width=300" width="230" class="align-left" height="307"/></a><br />
<ul>
<li>Dar pisca (acender os LEDs esquerdos ou direitos)</li>
<li>Sinalizar uma frenagem (acender os dois LEDs traseiros)</li>
</ul>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p>O diagrama em blocos da eletrônica original é:</p>
<p><img class="alignnone size-full wp-image-4076" src="https://mjrobot.files.wordpress.com/2016/05/original-block-diagram2.png?w=840" alt="Original Block Diagram"/></p>
<p>Em relação a mobilidade, nos projetos anteriores de robôs utilizamos a técnica de “Differential Steering” onde variando-se o sentido de giro das rodas, varia-se a direção do rob0, mas aqui se pode ver que o carrinho, apesar de também possuir dois motores DC , possui uma confirmação diferente de motores:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/05/fullsizerender-15.jpg?w=234&h=230" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/fullsizerender-15.jpg?w=234&h=230&width=234" width="234" class="align-left"/></a>O motor frontal, não possui nenhum controle de velocidade ou posição, sendo utilizado apenas para virar o carrinho “à direita”ou “à esquerda”, movendo-se simultaneamente todo o conjunto rodas/eixo frontal (mais ou menos como em um automóvel). Em geral o carrinho sempre se move para a frente em linha reta e o motor está desligado, deixando assim as rodas livres. Um comando para “virar à esquerda” p<a href="https://mjrobot.files.wordpress.com/2016/05/img_24732.jpg?w=307&h=168" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/img_24732.jpg?w=307&h=168&width=307" width="307" class="align-right"/></a>or exemplo, fará o motor girar, fazendo o mecanismo de engrenagens como um todo se mover para a esquerda. Enquanto o motor estiver alimentado o mecanismo ficará nessa posição limite e o carrinho continuará “virando à esquerda”).</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/05/turn_left2.png?w=562&h=325" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/turn_left2.png?w=562&h=325&width=700" width="700" class="align-full"/></a></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/05/img_3511.jpg?w=153&h=204" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/img_3511.jpg?w=153&h=204&width=153" width="231" class="align-left" height="308"/></a></p>
<p> </p>
<p>O motor traseiro está acoplado a um sistema redutor de velocidade por engrenagens e fornece torque variável as rodas traseiras (conjunto fixo). Pode-se assim variar a velocidade, mas não a direção (as duas rodas sempre girarão em um mesmo sentido).</p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p>. . </p>
<p></p>
<p></p>
<p></p>
<p></p>
<h4>RAQUEANDO A ELETRÔNICA EMBARCADA</h4>
<p>Uma vez que tudo foi identificado, é a hora de remover a eletrônica original, deixando somente os cabos dos motores e bateria. Como não vou voltar a usar a carcaça superior por enquanto, não me preocuparei com os LEDs originais.</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/05/07/raqueando-o-carrinho-de-controle-remoto/img_2451/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/img_2451.jpg?w=416&h=555&crop=1&width=300" width="286" class="align-left" height="381"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/05/07/raqueando-o-carrinho-de-controle-remoto/img_2475/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/img_2475.jpg?w=416&h=555&crop=1&width=300" width="300" class="align-right"/></a></div>
</div>
</div>
</div>
<p>No lugar do módulo eletrônico, usaremos um Arduino Uno, que será o responsável pela lógica do processamento, acionando os motores, LEDs e um Buzzer. O controle remoto que antes era conseguido por um sistema receptor de RF de 27MHz será agora substituído pelo modulo HC-06, o qual se comunicará com um dispositivo Android. A bateria original do carrinho será mantida exclusivamente para a alimentação dos motores via a H-Bridge L293D, pois os motores DC além de consumirem bastante corrente geram ruído devido a suas escovas. Pela maneira que o carrinho foi construído, o motor frontal consome bastante energia no momento em que recebe um comando de virar para um dos lados, pois seu eixo será travado e o consumo de corrente será alto. Para o Arduino usaremos uma bateria de 9V (Vin), sendo que o modulo HC-06 será alimentado pela saída de 5V do Arduino).</p>
<p>O novo diagrama de blocos para implementação do circuito é:</p>
<p><img class="alignnone size-full wp-image-4092" src="https://mjrobot.files.wordpress.com/2016/05/block-diagram1.png?w=840" alt="Block Diagram"/></p>
<p>Neste ponto é importante testar os motores individualmente. Usando uma bateria, alimente o motor e observe para que lado lado ele gira. Inverta a bateria e repita o teste anotando as cores dos fios:</p>
<p>No caso de meu carrinho, temos:</p>
<p>Front Motor:</p>
<ul>
<li>Yellow: LEFT</li>
<li>White: RIGH</li>
</ul>
<p>Rear Motor:</p>
<ul>
<li>Green: Backward</li>
<li>Blue: Forward</li>
</ul>
<h4> .</h4>
<h4>MONTAGEM FINAL</h4>
<p>O circuito (as cores dos fios do motor não são as corretas):</p>
<p><img class="alignnone size-full wp-image-4114" src="https://mjrobot.files.wordpress.com/2016/05/circuit.png?w=840" alt="circuit"/></p>
<p>O HW do novo carrinho à controle remoto está pronto para seus primeiros testes. Agora, falta implementar o SW e o aplicativo Android.</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/05/07/raqueando-o-carrinho-de-controle-remoto/img_2490/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/img_2490.jpg?w=532&h=399&crop=1&width=350" width="391" class="align-left" height="294"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/05/07/raqueando-o-carrinho-de-controle-remoto/img_2489/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/img_2489.jpg?w=300&h=399&crop=1&width=300" width="254" class="align-right" height="338"/></a></div>
</div>
</div>
</div>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p> </p>
<p></p>
<p> .</p>
<h4>O APLICATIVO ANDROID</h4>
<p><a href="https://mjrobot.files.wordpress.com/2016/01/mjrobot-bt-icon.jpg?w=113&h=113" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/01/mjrobot-bt-icon.jpg?w=113&h=113&width=113" width="113" class="align-left"/></a></p>
<p></p>
<p></p>
<p>Para controlar o carrinho, usaremos uma App que desenvolvi utilizando o MIT AppInventor 2: “MJRoBot BT Remote Control”. A app pode ser baixada gratuitamente da loja da Google através do link: <a href="https://play.google.com/store/apps/details?id=appinventor.ai_mjrovai.MJRoBot_II_BT_Command_V2&hl=en" target="_blank">MJRoBot BT Remote Control</a></p>
<p></p>
<p></p>
<p>A app possui uma interface simples, permitindo o envio de comandos ao modulo de BT tanto em modo TEXT, como diretamente via botões pre-programados (cada vez que um botão é pressionado, um caracter é enviado):</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/05/screenshot_2015-12-11-20-24-01.jpg?w=351&h=562" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/screenshot_2015-12-11-20-24-01.jpg?w=351&h=562&width=351" width="351" class="align-left"/></a>w: Forward</p>
<p>s: Backward</p>
<p>d: Right</p>
<p>a: Left</p>
<p>f: Stop</p>
<p>p: ON/OFF</p>
<p>m: Manual / Automatic</p>
<p>+: Speed+</p>
<p>-: Speed-</p>
<p> </p>
<p>Também existe uma janela de texto para mensagens recebidas do modulo BT. Esta característica é bem importante durante a fase de testes, pois pode ser usada da mesma maneira que o “Serial monitor”.</p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p>O Diagrama de blocos para o projeto no MIT appInventor2:</p>
<p><img class="alignnone size-full wp-image-4238" src="https://mjrobot.files.wordpress.com/2016/05/app_blocks.png?w=840" alt="app_Blocks"/></p>
<h4>O CÓDIGO ARDUINO</h4>
<p>O bloco principal do código é bem simples:</p>
<p></p>
<p><span style="color: #993300;"><em>void loop()</em></span></p>
<p><span style="color: #993300;"><em>{</em></span></p>
<p><span style="color: #993300;"><em> checkBTcmd(); // verify if a command is received from BT remote control</em></span></p>
<p><span style="color: #993300;"><em> receiveCmd ();</em></span></p>
<p><span style="color: #993300;"><em> if (turnOn) manualCmd ();</em></span></p>
<p><span style="color: #993300;"><em> else stopRobot ();</em></span></p>
<p><span style="color: #993300;"><em>}</em></span></p>
<p></p>
<p>A primeira coisa a se fazer é verificar se existe algum novo comando BT chegando. Quem checará isso é a função “checkBTcmd()”:</p>
<p></p>
<p><span style="color: #993300;"><em>void checkBTcmd() // verify if a command is received from BT remote control</em></span></p>
<p><span style="color: #993300;"><em>{</em></span></p>
<p><span style="color: #993300;"><em> if (BT1.available())</em></span></p>
<p><span style="color: #993300;"><em> {</em></span></p>
<p><span style="color: #993300;"><em> command = BT1.read();</em></span></p>
<p><span style="color: #993300;"><em> BT1.flush();</em></span></p>
<p><span style="color: #993300;"><em> }</em></span></p>
<p><span style="color: #993300;"><em>}</em></span></p>
<p></p>
<p>A variável “turnOn” é utilizada para ligar ou desligar o carrinho.</p>
<p>A função “receiveCmd()” será a encarregada de definir o status dessa variável em função do comando recebido do modulo BT. Observe que pela lógica usada, cada vez que o botão vermelho com o símbolo de “POWER” é pressionado, o caracter “p” será enviado pelo app e a a variável “turnOn”, mudará se valor (de 1 para 0 e vice e versa):</p>
<p></p>
<p><span style="color: #993300;"><em>void receiveCmd ()</em></span></p>
<p><span style="color: #993300;"><em>{</em></span></p>
<p><span style="color: #993300;"><em> switch (command)</em></span></p>
<p><span style="color: #993300;"><em> {</em></span></p>
<p><span style="color: #993300;"><em> case 'p':</em></span></p>
<p><span style="color: #993300;"><em> turnOn = !turnOn;</em></span></p>
<p><span style="color: #993300;"><em> command = 0;</em></span></p>
<p><span style="color: #993300;"><em> analogWrite(ledStatus, turnOn*128); // Robot ON - Led ON</em></span></p>
<p><span style="color: #993300;"><em> beep(outBuz, 1000, 100);</em></span></p>
<p><span style="color: #993300;"><em> BT1.print(" COMMAND ON/OFF");</em></span></p>
<p><span style="color: #993300;"><em> BT1.println('\n');</em></span></p>
<p><span style="color: #993300;"><em> delay(200); //Delay to call attention to mode change break;</em></span></p>
<p><span style="color: #993300;"><em> case 'm': //not used here, left as a spare button</em></span></p>
<p><span style="color: #993300;"><em> break;</em></span></p>
<p><span style="color: #993300;"><em> }</em></span></p>
<p><span style="color: #993300;"><em>}</em></span></p>
<p></p>
<p>Voltando ao loop principal, enquanto a variável “turnOn” é HIGH (1), a função “manualCmd()” executará um comando, dependendo do caracter recebido:</p>
<p><br/> <span style="color: #993300;"><em>void manualCmd()</em></span></p>
<p><span style="color: #993300;"><em>{</em></span></p>
<p><span style="color: #993300;"><em> switch (command)</em></span></p>
<p><span style="color: #993300;"><em> {</em></span></p>
<p><span style="color: #993300;"><em> case 'f':</em></span></p>
<p><span style="color: #993300;"><em> moveStop(); //turn off both motors</em></span></p>
<p><span style="color: #993300;"><em> state = command;</em></span></p>
<p><span style="color: #993300;"><em> break;</em></span></p>
<p><span style="color: #993300;"><em> case 'w':</em></span></p>
<p><span style="color: #993300;"><em> moveForward();</em></span></p>
<p><span style="color: #993300;"><em> state = command;</em></span></p>
<p><span style="color: #993300;"><em> break;</em></span></p>
<p><span style="color: #993300;"><em> case 'd':</em></span></p>
<p><span style="color: #993300;"><em> moveRight();</em></span></p>
<p><span style="color: #993300;"><em> break;</em></span></p>
<p><span style="color: #993300;"><em> case 'a':</em></span></p>
<p><span style="color: #993300;"><em> moveLeft();</em></span></p>
<p><em><span style="color: #993300;"> break;</span></em></p>
<p><span style="color: #993300;"><em> case 's':</em></span></p>
<p><span style="color: #993300;"><em> moveBackward();</em></span></p>
<p><span style="color: #993300;"><em> state = command;</em></span></p>
<p><span style="color: #993300;"><em> break;</em></span></p>
<p><span style="color: #993300;"><em> case '+':</em></span></p>
<p><span style="color: #993300;"><em> if (state == 'w')</em></span></p>
<p><span style="color: #993300;"><em> {</em></span></p>
<p><span style="color: #993300;"><em> motorSpeed = motorSpeed + 10;</em></span></p>
<p><span style="color: #993300;"><em> if (motorSpeed > MAX_SPEED) motorSpeed = MAX_SPEED;</em></span></p>
<p><span style="color: #993300;"><em> command = 'w';</em></span></p>
<p><span style="color: #993300;"><em> } else command = state;</em></span></p>
<p><span style="color: #993300;"><em> break;</em></span></p>
<p><span style="color: #993300;"><em> case '-':</em></span></p>
<p><span style="color: #993300;"><em> if (state == 'w') motorSpeed = motorSpeed - 10; </em></span></p>
<p><span style="color: #993300;"><em> if (motorSpeed < MIN_SPEED ) motorSpeed = MIN_SPEED;</em></span></p>
<p><span style="color: #993300;"><em> command = state;</em></span></p>
<p><span style="color: #993300;"><em> break;</em></span></p>
<p><span style="color: #993300;"><em> }</em></span></p>
<p><span style="color: #993300;"><em>}</em></span></p>
<p></p>
<p>Por exemplo se o comando “w” é recebido, a função específica para mover o carrinho para a frente “moveForward()” é executada.</p>
<p>Em caso “powerOn” esteja em HIGH e a tecla “POWER” seja pressionada, a variável “powerOn”, passará a LOW e a função “stopRobot()” será a executada ao invés de “manualCmd()”. Esta função garante que o motor traseiro esteja parado, os LEDs apagados e variáveis zeradas.</p>
<p></p>
<p><span style="color: #993300;"><em>void stopRobot ()</em></span></p>
<p><span style="color: #993300;"><em>{</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(ledBlue, LOW);</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(ledRed, LOW);</em></span></p>
<p><span style="color: #993300;"><em> state = 0;</em></span></p>
<p><span style="color: #993300;"><em> moveStop(); //turn off both motors</em></span></p>
<p><span style="color: #993300;"><em>}</em></span></p>
<p></p>
<p> .</p>
<p>ACIONANDO OS MOTORES DC VIA H-BRIDGE</p>
<p>Os motores frontal e traseiro estão ligados a ponte-H como mostrado abaixo:</p>
<p><img class="alignnone size-full wp-image-4304" src="https://mjrobot.files.wordpress.com/2016/05/h-bridge.png?w=840" alt="H-Bridge"/></p>
<p>e a cada um dos pinos do Arduino, os quais deverão ser definidos como OUTPUT, será atribuído uma variável:</p>
<p></p>
<p><span style="color: #993300;"><em>const int rearMtFw = 4; // Rear Motor - FW</em></span></p>
<p><span style="color: #993300;"><em>const int rearMtBw = 7; // Rear Motor - BW</em></span></p>
<p><span style="color: #993300;"><em>const int rearMtEne = 6; // Rear Motor - enable</em></span></p>
<p><span style="color: #993300;"><em>const int frontMtLeft = 2; // Front Motor - turn Left</em></span></p>
<p><span style="color: #993300;"><em>const int frontMtRight = 3; // Front Motor - turn right</em></span></p>
<p><span style="color: #993300;"><em>const int frontMtEne = 5; // Front Motor enable</em></span></p>
<p></p>
<p>Por exemplo, se desejamos mover o carrinho para a frente, a função “moveForward()” deverá colocar o pino 4 en HIGH e o pino 7 em LOW, isso fará com que a corrente flua “no sentido horário”, como mostrado no diagrama abaixo:</p>
<p><img class="alignnone size-full wp-image-4345" src="https://mjrobot.files.wordpress.com/2016/05/fw-example-h-bridge2.png?w=840" alt="FW example H-Bridge"/></p>
<p></p>
<p>O pino 6 é o “enable”, somente quando ele estiver em “HIGH”, a ponte permitirá o fluxo de corrente pelo motor. Como este pino possui característica PWM, a velocidade com que o motor girará, dependerá do valor da variável “motorSpeed”, no pino 6 (valor de 0 255).<br/> A função também deverá garantir que o motor frontal “gire livremente”, e para isso o pino 5, que é o pino de “enable” deverá estar em LOW (o status dos pinos 2 e 3 não importam, uma vez que o enable está el LOW). O LED vermelho, que funciona como “luz de ré”, deverá sempre estar apagado quando o carrinho se move para a frente:</p>
<p></p>
<p><span style="color: #993300;"><em>void moveForward() // rear motor FW</em></span></p>
<p><span style="color: #993300;"><em>{</em></span></p>
<p><span style="color: #993300;"><em> analogWrite(rearMtEne, motorSpeed);</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(rearMtFw, HIGH);</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(rearMtBw, LOW);</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(frontMtEne, LOW);</em></span></p>
<p><span style="color: #993300;"><em> digitalWrite(ledRed, LOW);</em></span></p>
<p><span style="color: #993300;"><em> delay(5);</em></span></p>
<p><span style="color: #993300;"><em>}</em></span></p>
<p></p>
<p>por analogia, é obvio que para o carrinho “mover para trás”, basta que o motor gire na direção contrária. Para isto, o pino 4 deverá estar em LOW e o pino 7 em HIGH. Note que nesse caso a “luz de ré”, deverá estar acesa. A função neste caso será:</p>
<p></p>
<p><em><span style="color: #993300;">void moveBackward() // rear motor BW</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> analogWrite(rearMtEne, motorSpeed);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(rearMtFw, LOW);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(rearMtBw, HIGH);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(frontMtEne, LOW);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(ledRed, HIGH);</span></em></p>
<p><em><span style="color: #993300;"> delay(5);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>O mesmo raciocínio pode ser utilizado para o motor frontal, somente que nesse caso, não existe controle de velocidade. Colocando o pino 2 (enable) em HIGH habilita o motor a “tentar girar”, para um lado ou para outro dependendo do status dos pinos 2 e 3:</p>
<p></p>
<p><em><span style="color: #993300;">void moveLeft() // front motor left</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(frontMtEne, HIGH);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(frontMtLeft, HIGH);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(frontMtRight, LOW);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(ledRed, LOW);</span></em></p>
<p><em><span style="color: #993300;"> delay(10);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
<p><em><span style="color: #993300;">//************************************//</span></em></p>
<p><em><span style="color: #993300;">void moveRight() // front motor right</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(frontMtEne, HIGH);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(frontMtLeft, LOW);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(frontMtRight, HIGH);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(ledRed, LOW);</span></em></p>
<p><em><span style="color: #993300;"> delay(10);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>Para parar o carrinho, basta colocar todas as saídas da ponte relativas ao motor traseiro em LOW, o que “travará” o eixo do motor (o motor frontal basta o enable estar em LOW):</p>
<p></p>
<p><em><span style="color: #993300;">void moveStop() //turn off rear motor</span></em></p>
<p><em><span style="color: #993300;">{</span></em></p>
<p><em><span style="color: #993300;"> analogWrite(rearMtEne, LOW);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(rearMtFw, LOW);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(rearMtBw, LOW);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(frontMtEne, LOW);</span></em></p>
<p><em><span style="color: #993300;"> digitalWrite(ledRed, LOW);</span></em></p>
<p><em><span style="color: #993300;"> delay(5);</span></em></p>
<p><em><span style="color: #993300;">}</span></em></p>
<p></p>
<p>Abaixo, você poderá encontrar o código completo para o Arduino:</p>
<p><span style="color: #0000ff;"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979595936?profile=original" target="_self"><span style="color: #0000ff;">MJRoBot_AutoBot.ino</span></a></span></p>
<p><span style="color: #0000ff;"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596081?profile=original" target="_self"><span style="color: #0000ff;">generalFuntions.ino</span></a></span></p>
<p><span style="color: #0000ff;"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596302?profile=original" target="_self"><span style="color: #0000ff;">motorRobot.ino</span></a></span></p>
<p><span style="color: #0000ff;"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598331?profile=original" target="_self"><span style="color: #0000ff;">robotDefines.h</span></a></span></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p><span style="font-size: 1em;">CONCLUSÃO</span></p>
<p><img class="alignnone size-full wp-image-3954" src="https://mjrobot.files.wordpress.com/2016/05/img_2488.jpg?w=840" alt="IMG_2488"/></p>
<p>O carrinho está devidamente raqueado e pronto para ganhar o mundo! Agora o céu é o limite! Comece, por exemplo instando sensores para evitar obstáculos, um HC-04 (ultra-som) funcionará bem, como vimos no caso do <a href="https://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/">“Mars Rover” tupiniquim</a>. Crie um novo comando e envie o “caracter” via texto (ou use o botão Man/Auto: caracter “m”, para o robô executar outras fincões (buzina, por exemplo).</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/05/servo-frontal.png?w=341&h=286" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/05/servo-frontal.png?w=341&h=286&width=341" width="341" class="align-left"/></a>Outra idéia interessante é melhorar a “dirigibilidade” do carrinho. O motor DC frontal poderia ser substituído por um servo de 180o que movimentaria o conjunto frontal de maneira linear, obtendo-se assim ângulos de virada variáveis. A foto ao lado é de um exemplo que encontrei a web. Não é exatamente o mecanismo de meu carrinho, mas mas mostra como poderia ficar.</p>
<p> </p>
<p>That’s all folks!</p>
<p>Como sempre, espero que este projeto ajude outras pessoas a encontrar seu caminho no apaixonante mundo da eletrônica e dos robôs!</p>
<p>Um abraço e até o próximo post!</p>
<p>Obrigado</p>
<p></p>
<p></p>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596529?profile=original" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979596529?profile=RESIZE_320x320" width="300" class="align-center"/></a></p>
</div>A edição de maio da Revista britânica MagPi, publicou matéria sobre meu projeto: "Mars Rover Tupiniquim", que apareceu aqui no Garagem em março.tag:labdegaragem.com,2016-05-02:6223006:BlogPost:5315472016-05-02T14:30:00.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p>Pessoal, </p>
<p>A <a href="http://storage.ning.com/topology/rest/1.0/file/get/1979594807?profile=original" target="_self"><img class="align-left" src="http://storage.ning.com/topology/rest/1.0/file/get/1979594807?profile=RESIZE_320x320" width="200"></img></a> edição de maio da revista britânica MagPi publicou uma matéria muito legal sobre meu Projeto "Mars Rover Tupiniquin" que apareceu aqui no Blog do Garagem (…</p>
<p>Pessoal, </p>
<p>A <a href="http://storage.ning.com/topology/rest/1.0/file/get/1979594807?profile=original" target="_self"><img width="200" src="http://storage.ning.com/topology/rest/1.0/file/get/1979594807?profile=RESIZE_320x320" width="200" class="align-left"/></a>edição de maio da revista britânica MagPi publicou uma matéria muito legal sobre meu Projeto "Mars Rover Tupiniquin" que apareceu aqui no Blog do Garagem (<a href="http://labdegaragem.com/profiles/blogs/projeto-prot-tipo-de-uma-esta-o-rob-tica-m-vel-para-captura-de">http://labdegaragem.com/profiles/blogs/projeto-prot-tipo-de-uma-esta-o-rob-tica-m-vel-para-captura-de</a>). Para quem não conhece, a MagPi é a revista oficial do RapsberryPi. Você pode baixar grátis as edições da revista em PDF. </p>
<p></p>
<p>A edição de maio (45) pode ser baixada no link: <a href="https://raspberrypi.org/magpi-issues/MagPi45.pdf">https://raspberrypi.org/magpi-issues/MagPi45.pdf</a></p>
<p></p>
<p>Espero que gostem!</p>
<p>(A reporter trocou o Marcelo por Marcio, mas está valendo! ;-)</p>
<p></p>
<p></p>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596708?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979596708?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979599221?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979599221?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>Robô explorador de labirintos, utilizando Inteligência Artificial com Arduinotag:labdegaragem.com,2016-04-29:6223006:BlogPost:5307642016-04-29T15:44:26.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p><span>Esta é a segunda e última parte de um projeto mais complexo, que explora a potencialidade de um robô seguidor de linha. Nesta etapa, aplicaremos conceitos de inteligência artificial na exploração de labirintos, implementando algoritmos que nos ajudarão a encontrar o caminho da saída mais curto e rápido.</span></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/img_3480.jpg?w=1200&h=0&crop=1" target="_blank"><img class="align-full" src="https://mjrobot.files.wordpress.com/2016/04/img_3480.jpg?w=1200&h=0&crop=1&width=700" width="700"></img></a></p>
<p>Este projeto foi desenvolvido a partir…</p>
<p><span>Esta é a segunda e última parte de um projeto mais complexo, que explora a potencialidade de um robô seguidor de linha. Nesta etapa, aplicaremos conceitos de inteligência artificial na exploração de labirintos, implementando algoritmos que nos ajudarão a encontrar o caminho da saída mais curto e rápido.</span></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/img_3480.jpg?w=1200&h=0&crop=1" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/img_3480.jpg?w=1200&h=0&crop=1&width=700" width="700" class="align-full"/></a></p>
<p>Este projeto foi desenvolvido a partir de meu último tutorial: <a href="http://labdegaragem.com/profiles/blogs/tutorial-rob-seguidor-de-linha-com-controle-pid-e-ajustes-por" target="_self">Robô seguidor de linha com controle PID e ajustes por aplicativo Android</a>. Depois de se conseguir desenvolver um robô com capacidade para seguir linhas, o próximo passo natural é sem dúvida, dar-lhe algum grau de inteligência. Assim, nessa etapa, o nosso querido “Rex, o Robô” tentará encontrar uma forma de escapar de um “labirinto” tomando o caminho mais curto e o mais rápido possível. A propósito, Rex odeia o Minotauro…..</p>
<p>A maioria dos labirintos, por mais complexa sua concepção possa parecer, foram essencialmente formados a partir de uma parede contínua com mitos cruzamentos e bifurcações. Se a parede circundante do objectivo final de um labirinto está ligado ao perímetro do labirinto na entrada, o labirinto sempre poderá ser resolvido mantendo-se uma mão em contacto com a parede, não importando os muitos desvios que possam existir. Estes labirintos “simples” são conhecido como “Simply-connected” ou “perfeitos”, ou em outras palavras, que não contêm loops.</p>
<p>Voltando ao nosso projeto, ele será dividido em duas partes:</p>
<p>1. (Primeira passada): O robô encontrará o seu caminho para sair de um labirinto perfeito desconhecido. Não importa onde você o colocar dentro do labirinto, ele sempre encontrará uma “solução de saída”.</p>
<p>2. (Segunda passada): Uma vez que o robô encontrou uma possível solução para sair do labirinto, ele deve otimizar-la, encontrando o caminho mais curto para ir do início ao fim.</p>
<p>O vídeo abaixo, mostra um exemplo do robô encontrando seu caminho para sair do labirinto (chegar “ao final”). Na primeira vez que o robô explora o labirinto, é claro que vai perder muito tempo “pensando” sobre o que fazer em todo e qualquer cruzamento. Para testar as possibilidades, ele tomará vários caminhos errados e becos sem saída, o que faz com que ele escolha caminhos mais longos e execute várias “marcha-rés” desnecessárias.</p>
<p>Durante esta”1ª passada”, o robô irá acumulando experiências, “tomando notas” sobre os diferentes cruzamentos e eliminando os atalhos ruins. Em sua “segunda passada”, o robô irá direta e rapidamente ao final do labirinto sem qualquer erro ou dúvida. Ao longo deste tutorial, exploraremos em detalhes como fazê-lo:</p>
<div class="jetpack-video-wrapper"><a href="https://www.youtube.com/watch?v=EiD1LNPm_24">https://www.youtube.com/watch?v=EiD1LNPm_24</a></div>
<div class="jetpack-video-wrapper"><h4>.</h4>
<h4>LISTA DE MATERIAIS:</h4>
<p>A lista de materiais é basicamente a mesmo que usamos com robô seguidor de linha, exceto que foram incluídos 2 Sensores adicionais para uma melhor precisão na detecção da cruzamentos à esquerda e a direita:</p>
</div>
<ul>
<li>Corpo (pode ser adaptado para as suas necessidades):<ul>
<li>2 quadrados de madeira (80x80mm)</li>
<li>3 Grampos de papel</li>
<li>2 rodas de madeira (diâmetro: 50 mm)</li>
<li>1 roda “solta” (Caster)</li>
<li>9 Elásticos</li>
<li>Fita 3M “Command”</li>
<li>Articulações plásticas para fixação do sensor</li>
</ul>
</li>
<li>Protoboard e fiação</li>
<li>2 conjuntos de baterias (4XNi-metal hidreto) – 5V cada conjunto</li>
<li>2 Servos de Rotação Contínua (SM-S4303R)</li>
<li>Arduino Nano</li>
<li>Módulo Bluetooth HC-06</li>
<li>5 sensores x Linha (TCRT5000 4CH Infrared Linha Pista Seguidor Módulo Sensor + 1 sensor de Pista independente)</li>
<li>2 sensores ZX03 (baseado no TCRT5000) Reflective Infrared Sensors (saída analógica)</li>
<li>1 LED</li>
<li>1 Botão</li>
</ul>
<p></p>
<p>.</p>
<h4>ALTERAÇÕES AO CORPO DO ROBÔ</h4>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><img src="https://mjrobot.files.wordpress.com/2016/04/img_3450.jpg?w=416&h=555&crop=1&width=200" width="200" class="align-left"/><a href="https://mjrobot.org/2016/04/28/robo-explorador-de-labirintos-utilizando-inteligencia-artificial-com-arduino/img_3449/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/img_3449.jpg?w=416&h=555&crop=1&width=200" width="200" class="align-right"/></a></div>
</div>
</div>
<div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="https://mjrobot.org/2016/04/28/robo-explorador-de-labirintos-utilizando-inteligencia-artificial-com-arduino/img_3453/" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/img_3453.jpg?w=836&h=627&crop=1&width=200" width="200" class="align-right"/></a></div>
</div>
</div>
</div>
<p>Retirar o conjunto original dos 5 Sensores e fixar os novos sensores reflectivos aos extremos esquerdo e direito da barra de suporte plástica.</p>
<p>É aconselhável manter os 7 sensores o mais alinhado possível.</p>
<p></p>
<p></p>
<p><span style="font-size: 1em;">.</span></p>
<h4>INSTALAÇÃO E TESTES DOS NOVOS SENSORES</h4>
<p>A nova matriz de 7 sensores, é montado de forma a que os 5 originais sejam utilizados exclusivamente para o controlo PID e detecção da “linha completa” (explicado mais adiante) e que os novos 2 sensores somente para a detecção dos cruzamentos a esquerda e a direita.</p>
<p>Como uma rápida revisão, vamos lembrar como os 5 sensores originais “digitais” trabalham:</p>
<p>Se um sensor está centrado em relação à linha preta, este irá produzir um sinal HIGH. Por outro lado, o espaço entre os sensores devem ser calculados de tal modo a permitir que dois sensores possam cobrir a largura total da linha preta produzindo assim um sinal HIGH simultaneamente em ambos os sensores.</p>
<p>Como os 2 novos sensores “analógicos” trabalham:</p>
<p>Se um dos sensores está centrado em relação à linha preta, o resultado observado na saída do ADC interno do Arduino será geralmente menor que “100” (lembre-se que o ADC produz uma saída que vai de 0 a 1023). Sobre superfícies mais claras, o valor de saída deverá ser maior (500 a 600 sobre papel branco, por exemplo). Estes valores devem ser testado em diferentes situações de luz de superfície e de materiais para se definir a constante LIMIAR (“THRESHOLD”) correta a ser usada (ver o quadro aqui).</p>
<p>Abaixo, o diagrama mostrando os componentes conectados ao Arduino:</p>
<p><img class="alignnone size-full wp-image-3461" src="https://mjrobot.files.wordpress.com/2016/04/maze-solver-circuit.png?w=840" alt="Maze Solver Circuit"/></p>
<p><span>Olhando o código do Arduino, cada um dos sensores será definido com um nome específico:</span></p>
<p></p>
<p><em>const int lineFollowSensor0 = 12; //Using Digital input</em></p>
<p><em>const int lineFollowSensor1 = 18; //Using Analog Pin A4 as Digital input</em></p>
<p><em>const int lineFollowSensor2 = 17; //Using Analog Pin A3 as Digital input</em></p>
<p><em>const int lineFollowSensor3 = 16; //Using Analog Pin A2 as Digital input</em></p>
<p><em>const int lineFollowSensor4 = 19; //Using Analog Pin A5 as Digital input</em></p>
<p><em>const int farRightSensorPin = 0; //Analog Pin A0</em></p>
<p><em>const int farLeftSensorPin = 1; //Analog Pin A1</em></p>
<p></p>
<p>Recordando, as possíveis combinações de saída para a matriz de 5 sensores original do seguidor de linha são:</p>
<ul>
<li>0 0 0 0 1</li>
<li>0 0 0 1 1</li>
<li>0 0 0 1 0</li>
<li>0 0 1 1 0</li>
<li>0 0 1 0 0</li>
<li>0 1 1 0 0</li>
<li>0 1 0 0 0</li>
<li>1 1 0 0 0</li>
<li>1 0 0 0 0</li>
</ul>
<p>Com a adição dos 2 novos sensores, as suas saídas possíveis são:</p>
<ul>
<li>Sensor Esquerdo: Saída Analógica maior ou menor do que o valor definido de THRESHOLD</li>
<li>Sensor Direito: Saída Analógica maior ou menor do queo valor definido de THRESHOLD</li>
</ul>
<p>A fim de armazenar os valores de cada um dos sensores uma variável tipo matriz (Array) é criada para os sensores digitais originais 5:</p>
<p></p>
<p><em>int LFSensor[5]={0, 0, 0, 0, 0};</em></p>
<p><em> </em></p>
<p>E duas variáveis do tipo inteiras para os 2 novos sensores analógicos:</p>
<p></p>
<p><em>int farRightSensor = 0;<br/>int farLeftSensor = 0;</em></p>
<p></p>
<p>As variáveis serão constantemente actualizadas dependendo do estado de cada um dos sensores:</p>
<p></p>
<p><em>LFSensor[0] = digitalRead(lineFollowSensor0);</em></p>
<p><em>LFSensor[1] = digitalRead(lineFollowSensor1);</em></p>
<p><em>LFSensor[2] = digitalRead(lineFollowSensor2);</em></p>
<p><em>LFSensor[3] = digitalRead(lineFollowSensor3);</em></p>
<p><em>LFSensor[4] = digitalRead(lineFollowSensor4);</em></p>
<p><em>farRightSensor = analogRead(farRightSensorPin);</em></p>
<p><em>farLeftSensor = analogRead(farLeftSensorPin);</em></p>
<p></p>
<p>Possuindo 5 sensores, como se viu no projeto do Robô seguidor de linha, se permite a geração de uma “variável de erro” que ajudará a controlar a posição do robô sobre a linha. Essa variável de erro será mantida e uma nova denominada “mode” será incluída para saber se o robô está seguindo uma linha, sobre uma linha contínua, uma intersecção ou fora da linha.</p>
<p>Esta variável “mode” será usada também com os novos sensores de esquerda e direita. Consideremos que os novos sensores da esquerda e da direita geraram 3 estados possíveis: H (maior do que THRESHOLD), L (menor do que oTHRESHOLD) e X (irrelevante). Para as saídas digitais, manteremos “0”, “1” e também introduziremos o “X”:</p>
<p><img class=" wp-image-3453 alignnone" src="https://mjrobot.files.wordpress.com/2016/04/intersection.png?w=431&h=323" alt="Intersection" width="431" height="323"/></p>
<p></p>
<ul>
<li>X 1 1 1 1 1 X ==> mode = CONT_LINE; error = 0;</li>
<li>H 0 X X X X L==> mode = RIGHT_TURN; error = 0; (Veja o exemplo na imagem acima)</li>
<li>L X X X X 0 H==> mode = LEFT_TURN; error = 0;</li>
<li>X 0 0 0 0 0 X ==> mode = NO_LINE; error = 0;</li>
<li>H 0 0 0 0 1 H ==> mode = FOLLOWING_LINE; error = 4;</li>
<li>H 0 0 0 1 1 H ==> mode = FOLLOWING_LINE; error = 3;</li>
<li>H 0 0 0 1 0 H ==> mode = FOLLOWING_LINE; error = 2;</li>
<li>H 0 0 1 1 0 H ==> mode = FOLLOWING_LINE; error = 1;</li>
<li>H 0 0 1 0 0 H ==> mode = FOLLOWING_LINE; error = 0;</li>
<li>H 0 1 1 0 0 H ==> mode = FOLLOWING_LINE; error = -1;</li>
<li>H 0 1 0 0 0 H ==> mode = FOLLOWING_LINE; error = -2</li>
<li>H 1 1 0 0 0 H ==> mode = FOLLOWING_LINE; error = -3;</li>
<li>H 1 0 0 0 0 H ==> mode = FOLLOWING_LINE; error = -4;</li>
</ul>
<p>Assim, a implementação da lógica acima na função desenvolvida para o robô seguidor de linha, <em>void readLFSsensors(), </em></p>
<p>retornará as variáveis “mode” e “error” que serão utilizados na lógica do programa.</p>
<p></p>
<p>É importante testar a lógica dos sensores antes de seguir com o projeto. O código final do Arduino inclui funções criadas especificamente para fins de teste. </p>
<pre>.</pre>
<h4>RESOLVENDO O LABIRINTO – A REGRA DA MÃO ESQUERDA</h4>
<p>Como discutido na introdução deste tutorial, a maioria dos labirintos são essencialmente formados a partir de uma parede contínua com muitos cruzamentos e desvios.</p>
<p>Pesquisando na <a href="https://en.wikipedia.org/wiki/Maze_solving_algorithm" target="_blank">Wikipedia</a>, aprendemos que “o seguidor da parede” é o algorítmo mais conhecido para percorrer labirintos. É também conhecido como “regra da mão esquerda” ou a “regra da mão direita”. Se o labirinto é simplesmente conectado, isto é, todos as suas paredes são ligadas entre si, mantendo-se uma mão em contato com uma das paredes do labirinto é garantido que chegará a uma saída. Usaremos aqui a “Regra da mão esquerda”.</p>
<p>Em resumo, a regra da mão esquerda pode ser descrito como:</p>
<ul>
<li>Coloque a mão esquerda na parede.</li>
<li>Comece a andar para a frente</li>
<li>Em cada cruzamento, e ao longo do labirinto, manter a sua mão esquerda tocando na parede à sua esquerda.</li>
<li>Eventualmente, você vai chegar ao final do labirinto. Você provavelmente não vai seguir o caminho mais curto e mais direto, mas você chegará lá.</li>
</ul>
<p>Portanto, a chave aqui é identificar as intersecções, definindo que medidas tomar com base nas regras acima. Especificamente no nosso tipo de labirinto em 2D , podemos encontrar 8 tipos diferentes de intersecções :</p>
<p></p>
<p><img class="alignnone size-full wp-image-3555 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/04/intersections-types.png?w=840" alt="Intersections types"/></p>
<p></p>
<p>Olhando a imagem acima, podemos perceber que as possíveis ações nos cruzamentos são:</p>
<ol>
<li>Em um “cruzamento tipo cruz”<ul>
<li>Vá para a esquerda ou</li>
<li>Vá para a direita ou</li>
<li>Siga em frente ou</li>
</ul>
</li>
<li>Em um “T”:<ul>
<li>Vá para a esquerda ou</li>
<li>Vá para a direita</li>
</ul>
</li>
<li>Em um “virar somente a direita”:<ul>
<li>Vá para a direita</li>
</ul>
</li>
<li>Em um “virar somente a esquerda”:<ul>
<li>Vá para a esquerda</li>
</ul>
</li>
<li>Em um a frente ou esquerda:<ul>
<li>Vá para a esquerda ou</li>
<li>Siga em frente</li>
</ul>
</li>
<li>Em um a frente ou ou a direita:<ul>
<li>Vá para a direita ou</li>
<li>Siga em frente</li>
</ul>
</li>
<li>Em um beco sem saída:<ul>
<li>Volte</li>
</ul>
</li>
<li>No final do labirinto:<ul>
<li>Pare</li>
</ul>
</li>
</ol>
<p>Aplicando-se a “regra da mão esquerda” a lista acima, será reduzida a apenas uma opção para uma cada uma das possibilidades:</p>
<ol>
<li>Em um “cruzamento tipo cruz”<ul>
<li>Vá para a esquerda</li>
</ul>
</li>
<li>Em um “T” (Transversal):<ul>
<li>Vá para a esquerda</li>
</ul>
</li>
<li>Em um “virar somente a direita”:<ul>
<li>Vá para a direita</li>
</ul>
</li>
<li>Em um “virar somente a esquerda”:<ul>
<li>Vá para a esquerda</li>
</ul>
</li>
<li>Em um a frente ou esquerda:<ul>
<li>Vá para a esquerda</li>
</ul>
</li>
<li>Em um a frente ou ou a direita:<ul>
<li>Siga em frente</li>
</ul>
</li>
<li>Em um beco sem saída:<ul>
<li>Volte</li>
</ul>
</li>
<li>No final do labirinto:<ul>
<li>Pare</li>
</ul>
</li>
</ol>
<p>Estamos quase lá. Quando o robô atinge um beco sem saída é fácil identificá-lo, porque não existem situações ambíguas (já implementamos essa ação com o Robô seguidor de linha). O problema está quando o robô encontra uma “linha” por exemplo, pois a linha pode ser parte de um cruzamento tipo “cruz” (1) ou de um “T” (2) ou mesmo um “Final” (8). Além disso, quando o robô chega a um “virar à esquerda ou à direita”, esses cruzamentos podem ser os do tipo simples (opções 3 ou 4) ou opções que podem ir para a frente (5 ou 6). Para se descobrir exatamente em que tipo de intersecção está o robô, é necessário incorporar um passo adicional: o robô deve “dar um passinho a frente” ou seja rodar o que chamamos de “extra inch” e assim “ver” o que vem por adiante:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/maze4.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/maze4.png?w=840&width=710" width="710" class="align-full"/></a><br/>Em termos de fluxo, todas as acções possíveis podem ser descritas como:</p>
<ul>
<li>Em um beco sem saída:<ul>
<li>Volte</li>
</ul>
</li>
<li>Em uma linha:<ul>
<li>Executar uma polegada extra</li>
<li>Se há uma linha:<ul>
<li>É uma “cruz” ==> Ir para ESQUERDA</li>
</ul>
</li>
<li>Se não houver nenhuma linha:<ul>
<li>é um “T” ==> Ir para ESQUERDA</li>
</ul>
</li>
<li>Se houver outra linha:<ul>
<li>É o fim de Maze ==> PARAR</li>
</ul>
</li>
</ul>
</li>
<li>Em uma curva à direita:<ul>
<li>Executar uma polegada extra</li>
<li>se há uma linha:<ul>
<li>É ir a frente ou virar a direita ==> ir direto</li>
</ul>
</li>
<li>Se não houver nenhuma linha:<ul>
<li>é um virar obrigatoriamente a direita==> Ir para DIREITA</li>
</ul>
</li>
</ul>
</li>
<li>Em uma curva à esquerda:<ul>
<li>Executar uma polegada extra</li>
<li>se há uma linha:<ul>
<li>É ir a frente ou virar a esquerda ==> virar a esquerda</li>
</ul>
</li>
<li>Se não houver nenhuma linha:<ul>
<li>é um virar obrigatoriamente a esquerda==> Ir para ESQUERDA</li>
</ul>
</li>
</ul>
</li>
</ul>
<p></p>
<p>Note-se que de facto, no caso de um “virar à esquerda”, você poderá pular o teste porque o robô tomará à esquerda de qualquer maneira. Deixei a explicação mais genérica somente para claridade. No código real ignorarei este teste.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/img_3474.jpg?w=307&h=399" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/img_3474.jpg?w=307&h=399&width=307" width="188" class="align-left" height="244"/></a></p>
<p> </p>
<p></p>
<p></p>
<p>A foto ao lado , é de um labirinto bem simples que desenhei no chão do meu laboratório, usando fita isolante de 18mm (3/4) que uso para testes (ainda bem que minha mãe não viu!!!! ;-0:</p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p>.</p>
<h4>APLICANDO O ALGORÍTMO “LEFT HAND ON THE WALL” AO CÓDIGO DO ARDUINO</h4>
<p>Uma vez que já temos a função readLFSsensors () modificada, para incluir os 2 sensores adicionais deveremos também re-escrever a função “Loop” introduzindo o algoritmo como descrito anteriormente:</p>
<p></p>
<p><em>void loop()</em></p>
<p><em>{</em></p>
<p><em> readLFSsensors();</em></p>
<p><em> switch (mode)</em></p>
<p><em> {</em></p>
<p><em> case NO_LINE:</em></p>
<p><em> motorStop();</em></p>
<p><em> goAndTurn (LEFT, 180);</em></p>
<p><em> break;</em></p>
<p><em> case CONT_LINE:</em></p>
<p><em> runExtraInch();</em></p>
<p><em> readLFSsensors();</em></p>
<p><em> if (mode == CONT_LINE) mazeEnd();</em></p>
<p><em> else goAndTurn (LEFT, 90); // or it is a "T" or "Cross"). In both cases, goes to LEFT</em></p>
<p><em> break;</em></p>
<p><em> case RIGHT_TURN:</em></p>
<p><em> runExtraInch();</em></p>
<p><em> readLFSsensors();</em></p>
<p><em> if (mode == NO_LINE) goAndTurn (RIGHT, 90);</em></p>
<p><em> break;</em></p>
<p><em> case LEFT_TURN:</em></p>
<p><em> goAndTurn (LEFT, 90);</em></p>
<p><em> break;</em></p>
<p><em> case FOLLOWING_LINE:</em></p>
<p><em> followingLine();</em></p>
<p><em> break;</em></p>
<p><em> }</em></p>
<p><em>}</em></p>
<p></p>
<p>Algumas funções importantes aparecem aqui.</p>
<p>followingLine() é a mesma utilizada com o robô seguidor de linha, que quando se está apenas seguindo uma linha, deve-se: calcular o PID e controlar os motores, dependendo dos valores dos ganhos da malha de controle usando a função: motorPIDcontrol ();</p>
<p></p>
<p>runExtraInch (): vai empurrar o robô para a frente um pouquinho. Quanto o robô se moverá, dependerá do tempo que você usa na função delay(), antes que mande parar os motores.</p>
<p></p>
<p><em>void runExtraInch(void)<br/></em></p>
<p><em>{</em></p>
<p><em> motorPIDcontrol();</em></p>
<p><em> delay(extraInch);</em></p>
<p><em> motorStop();</em></p>
<p><em>}</em></p>
<p></p>
<p>goAndTurn (direction, angle): Esta função é importante, porque você na verdade não pode virar o robô, tão logo perceba o tipo de intersecção em que está. Lembre-se que projectamos um robô do tipo diferencial que, quando faz curvas, “gira em torno do seu eixo”. Assim, para sair de um cruzamento, girar 90 graus e continuar movendo-se sobre a linha, o centro das rodas deve obrigatoriamente estar alinhado com o centro da intersecção. Uma vez que a linha dos sensores está à frente do eixo das rodas, o robô deve mover-se para a frente para alinhá-los. Os motores devem funcionar por um tempo “t” dependendo da distância entre a linha dos sensores e o eixo dos motores ( “d”), velocidade e tamanho das rodas. Esta constante de tempo “t” é no código: adjGoAndTurn, que deve ser ajustada dependendo de seu projeto:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/turn_explanation.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/turn_explanation.png?w=840&width=710" width="710" class="align-full"/></a></p>
<p><em>void goAndTurn(int direction, int degrees)<br/>{</em></p>
<p><em> motorPIDcontrol();</em></p>
<p><em> delay(adjGoAndTurn);</em></p>
<p><em> motorTurn(direction, degrees);</em></p>
<p><em>}</em></p>
<p></p>
<p>Neste ponto, o robô já está “resolvendo um labirinto”! Você acabou de terminar o “Primeiro Passo”. Não importa onde você começar dentro de um labirinto, você chegará ao final.<br/> Abaixo, um vídeo mostrando um teste para esta fase do projeto:</p>
<p></p>
<div class="jetpack-video-wrapper"><span style="font-size: 1em;"><span><a href="https://youtu.be/HE541eBFaow">https://youtu.be/HE541eBFaow</a></span></span></div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><span style="font-size: 1em;">.</span></div>
<div class="jetpack-video-wrapper"><span style="font-size: 1em;">TOMANDO NOTA DO CAMINHO</span></div>
<p></p>
<p>Consideremos o exemplo abaixo:</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/maze1.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/maze1.png?w=840&width=710" width="710" class="align-full"/></a></p>
<p>Partindo do ponto escolhido, o robô encontrará 15 Interseções antes de chegar ao final do labirinto:</p>
<ol>
<li>Esquerda (L)</li>
<li>Back (B)</li>
<li>Esquerda (L)</li>
<li>Esquerda (L)</li>
<li>Esquerda (L)</li>
<li>Back (B)</li>
<li>Reto (S)</li>
<li>Back (B)</li>
<li>Esquerda (L)</li>
<li>Esquerda (L)</li>
<li>Back (B)</li>
<li>Reto (S)</li>
<li>Esquerda (L)</li>
<li>Esquerda (L)</li>
<li>Fim</li>
</ol>
<p>O que deve ser feito em qualquer um desses cruzamentos é “salvar a decisão tomada” na mesma sequência em que aconteça. Para isso, vamos criar uma nova variável (matriz) que irá armazenar o caminho que o robô tenha tomado:</p>
<p>A variável path[] e 2 índices variáveis, serão utilizados em conjunto para se gravar os passos:</p>
<p></p>
<p><em>char path[100] = "";</em> <br/> <em>unsigned char pathLength = 0; // the length of the</em> <br/> <em>path int pathIndex = 0; // used to reach an specific array element.</em></p>
<p></p>
<p>Voltando ao exemplo, uma vez percorrido todo o circuito, as variáveis ficariam:</p>
<p>path = [LBLLLBSBLLBSLL] e pathLengh = 14</p>
<h4>.</h4>
<h4>SIMPLIFICANDO (OTIMIZANDO) O CAMINHO</h4>
<p>Voltemos ao nosso exemplo. Olhando para o primeiro grupo de cruzamentos, percebemos que o primeiro ramo esquerdo é na verdade um “Dead End”, e assim, se o robô em vez de um “lateral-esquerdo-esquerdo” apenas tivesse seguido reto nesse primeiro cruzamento, uma grande quantidade de energia e tempo seriam salvas! Em outras palavras, uma sequência do tipo “LBL”, de facto, seria o mesmo que “S”.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/maze2.png?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/maze2.png?w=840&width=710" width="710" class="align-full"/></a></p>
<p>Isso é exatamente como o caminho completo pode ser otimizado. Se você analisar todas as possibilidades onde um “U turn” (back) é utilizado, o conjunto de 3 cruzamentos onde o”U-Turn” ( “B”) aparece (“xBx”) poderá ser reduzido para apenas um.</p>
<p>A descrição acima é apenas um exemplo, abaixo podemos encontrar a lista completa de possibilidades:</p>
<p>LBR = B<br/>LBS = R<br/>RBL = B<br/>SBL R =<br/>SBS = B<br/>LBL = S</p>
<p>Aplicando-se as substituições acima para o caminho completo de nosso exemplo, podemos reduzi-lo a:</p>
<p>path = [<span>LBL</span>LLBSBLLBSLL] ==> LBL = S</p>
<p>path = [SL<span>LBS</span>BLLBSLL] ==> LBS = R</p>
<p>path = [SL<span>RBL</span>LBSLL] ==> RBL = B</p>
<p>path = [S<span>LBL</span>BSLL] ==> LBL = S</p>
<p>path = [S<span>SBS</span>LL] ==> SBS = B</p>
<p>path = [<span>SBL</span>L] ==> SBL = R</p>
<p>path = [RL]</p>
<p></p>
<p>Olhando para o exemplo, é muito claro que se o robô gira para a DIREITA logo no primeiro cruzamento e depois disso, à esquerda, ele chegará ao final do labirinto pelo caminho mais curto!</p>
<p><img class="alignnone size-full wp-image-3769 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/04/maze3.png?w=840" alt="Maze3"/></p>
<p></p>
<p>A primeira passada será consolidada na função mazeSolve (). Esta função é, de facto, a função loop () utilizada anteriormente, onde se incorporaram as etapas de armazenamento e otimização do caminho. Quando a primeira passada termina, a variável path[] conterá o caminho já optimizado.</p>
<p>Uma nova variável é introduzida para sinalizar o final da “passada”:</p>
<p></p>
<p>unsigned int status = 0; // solving = 0; reach end = 1</p>
<p></p>
<p>Abaixo a função completa para a primeira etapa do programa:</p>
<p><em>void mazeSolve(void)<br/>{</em></p>
<p><em> while (!status)</em></p>
<p><em> {</em></p>
<p><em> readLFSsensors();</em></p>
<p><em> switch (mode)</em></p>
<p><em> {</em></p>
<p><em> case NO_LINE:</em></p>
<p><em> motorStop();</em></p>
<p><em> goAndTurn (LEFT, 180);</em></p>
<p><em><span> recIntersection('B');</span></em></p>
<p><em> break;</em></p>
<p><em> case CONT_LINE:</em></p>
<p><em> runExtraInch();</em></p>
<p><em> readLFSsensors();</em></p>
<p><em> if (mode != CONT_LINE) {goAndTurn (LEFT, 90);<span>recIntersection('L')</span>;}</em></p>
<p><em> else mazeEnd();</em></p>
<p><em> break;</em></p>
<p><em> case RIGHT_TURN:</em></p>
<p><em> runExtraInch();</em></p>
<p><em> readLFSsensors();</em></p>
<p><em> if (mode == NO_LINE) {goAndTurn (RIGHT, 90);<span>recIntersection('R')</span>;}</em></p>
<p><em> else <span>recIntersection('S')</span>;</em></p>
<p><em> break;</em></p>
<p><em> case LEFT_TURN:</em></p>
<p><em> goAndTurn (LEFT, 90);</em></p>
<p><em><span> recIntersection('L')</span>;</em></p>
<p><em> break;</em></p>
<p><em> case FOLLOWING_LINE:</em></p>
<p><em> followingLine();</em></p>
<p><em> break;</em></p>
<p><em> }</em></p>
<p><em> }</em></p>
<p><em>}</em></p>
<p></p>
<p>Aqui uma nova função foi introduzida: recIntersection (direction)</p>
<p>Esta função será a usada para armazenar as decisões tomadas nos cruzamentos e também para chamar outra importante função: simplifyPath(), que irá otimizando “em tempo real” o grupo de 3 cruzamentos envolvendo “U-Turn”, como vimos anteriormente.</p>
<p></p>
<p><em>void recIntersection(char direction)<br/>{</em></p>
<p><em> path[pathLength] = direction; // Store the intersection in the path variable.</em></p>
<p><em> pathLength ++;</em></p>
<p><em> simplifyPath(); // Simplify the learned path.</em></p>
<p><em>}</em></p>
<p></p>
<p>O crédito para a criação da função simplifyPath () é de Patrick McCabe. Eu apenas a incluí ao meu código (para mais detalhes, visite <a href="http://patrickmccabemakes.com/tutorials/Maze_Solving/">patrickmccabemakes.com</a>):</p>
<p></p>
<p>.</p>
<h4>A SEGUNDA PASSADA: RESOLVENDO O LABIRINTO O MAIS RÁPIDO POSSÍVEL!</h4>
<p>O programa principal: loop () é bem simples:</p>
<p></p>
<p><em>void loop() <br/>{</em></p>
<p><em> ledBlink(1);</em></p>
<p><em> readLFSsensors(); <br/></em></p>
<p><em><span> mazeSolve(); // First pass to solve the maze</span></em></p>
<p><em> ledBlink(2);</em></p>
<p><em> </em></p>
<p><em>while (digitalRead(buttonPin) { }</em></p>
<p><em> pathIndex = 0;</em></p>
<p><em> status = 0;</em></p>
<p><span><em> mazeOptimization(); // Second Pass: run the maze as fast as possible</em></span></p>
<p><em> ledBlink(3);</em></p>
<p><em>}</em></p>
<p></p>
<p>Assim, quando a primeira passada termina, o que devemos fazer é apenas “alimentar” o robô com o caminho otimizado. Ele vai começar a percorrer o labirinto novamente e quando uma intersecção for encontrado, ele não mais tomará decisões, mas simplesmente seguirá o que está armazenado na variável path [].</p>
<p>Para a segunda passada usamos a função mazeOptimization(), que por sua vez, chama a função mazeTurn(path[]) que comandará os movimentos do robô nessa segunda passada:</p>
<p><em>void mazeOptimization (void)<br/>{</em></p>
<p><em> while (!status)</em></p>
<p><em> {</em></p>
<p><em> readLFSsensors();</em></p>
<p><em> switch (mode)</em></p>
<p><em> {</em></p>
<p><em> case FOLLOWING_LINE:</em></p>
<p><em> followingLine();</em></p>
<p><em> break;</em></p>
<p><em> case CONT_LINE:</em></p>
<p><em> if (pathIndex >= pathLength) mazeEnd ();</em></p>
<p><em> else {<span>mazeTurn (path[pathIndex])</span>; pathIndex++;}</em></p>
<p><em> break;</em></p>
<p><em> case LEFT_TURN:</em></p>
<p><em> if (pathIndex >= pathLength) mazeEnd ();</em></p>
<p><em> else {<span>mazeTurn (path[pathIndex])</span>; pathIndex++;}</em></p>
<p><em> break;</em></p>
<p><em> case RIGHT_TURN:</em></p>
<p><em> if (pathIndex >= pathLength) mazeEnd ();</em></p>
<p><em> else {<span>mazeTurn (path[pathIndex]</span>); pathIndex++;}</em></p>
<p><em> break;</em></p>
<p><em> }</em></p>
<p><em> }</em></p>
<p><em>}</em></p>
<p></p>
<p><em>void mazeTurn (char dir) <br/>{</em></p>
<p><em> switch(dir)</em></p>
<p><em> {</em></p>
<p><em> case 'L': // Turn Left</em></p>
<p><em> goAndTurn (LEFT, 90);</em></p>
<p><em> break;</em></p>
<p><em> case 'R': // Turn Right</em></p>
<p><em> goAndTurn (RIGHT, 90);</em></p>
<p><em> break;</em></p>
<p><em> case 'B': // Turn Back</em></p>
<p><em> goAndTurn (RIGHT, 800);</em></p>
<p><em> break;</em></p>
<p><em> case 'S': // Go Straight</em></p>
<p><em> runExtraInch();</em></p>
<p><em> break;</em></p>
<p><em> }</em></p>
<p><em>}</em></p>
<p></p>
<p>A segunda passada está feita!</p>
<p>O vídeo abaixo mostra o exemplo trabalhado aqui completo, onde Rex encontra seu caminho para livrar-se do Minotauro!</p>
<div class="jetpack-video-wrapper"></div>
<div class="jetpack-video-wrapper"><a href="https://www.youtube.com/watch?v=mtK27g5GteM">https://www.youtube.com/watch?v=mtK27g5GteM</a></div>
<div class="jetpack-video-wrapper"></div>
<p></p>
<p>O código Arduino completo para este projeto, poderá ser encontrado nos links abaixo:</p>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596593?profile=original" target="_self">smart_MJRoBot_Maze_Solve_Phase_2_with__Optimization.ino</a></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596900?profile=original" target="_self">generalFunctions.ino</a></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598329?profile=original" target="_self">mazeFunctions.ino</a></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598408?profile=original" target="_self">motorFuntions.ino</a></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598532?profile=original" target="_self">sensorFuntions.ino</a></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598554?profile=original" target="_self">robotDefines.h</a></p>
<p></p>
<h4>.</h4>
<h4>USANDO O APLICATIVO ANDROID PARA O AJUSTE</h4>
<p>A App Android desenvolvido para o projeto do Robô seguidor de Linha também pode ser usado aqui. O código Arduino apresentado na última etapa já inclui comunicação com o dispositivo Android, mas se não quiser usar-lo não há problema, porque o código é “transparente”.</p>
<p>Eu usei bastante o dispositivo Android durante o projeto para enviar dados de teste do robô para o dispositivo, utilizando-se o campo de “Mensagem recebida”.</p>
<p>Diversas variáveis devem ser bem definidas, a fim de garantir que o robô gire corretamente. Os mais importantes estão abaixo (os marcados em negrito tive mudar-los várias vezes):</p>
<ul>
<li>const int power = 250;</li>
<li>const int iniMotorPower = 250;</li>
<li><strong>const int adj = 0;</strong></li>
<li><strong>float adjTurn = 8;</strong></li>
<li>int extraInch = 200;</li>
<li><strong>int adjGoAndTurn = 800;<br/></strong></li>
<li><strong>THRESHOLD = 150</strong></li>
</ul>
<p></p>
<h4>CONCLUSÃO</h4>
<p>Esta é a segunda e última parte de um projeto complexo, explorando a potencialidade de um robô seguidor de linha, onde aplicando-se conceitos de inteligência artificial se conseguiu explorar labirintos, encontrando o caminho da saída mais curto e rápido.</p>
<p>Aproveito também a pedir a vocês, amigos garagistas que façam uma visita a meu post no Instructables.com abaixo e se gostarem, que votem no tutorial, que está concorrendo aos Contests ROBOTICS e "SENSORS" (é só clicar na bandeirinha laranja no canto superior direito da página). Muito Obrigado. </p>
<p></p>
<p><a href="http://www.instructables.com/id/Maze-Solver-Robot-Using-Artificial-Intelligence-Wi/" target="_blank">VOTAR: Maze Solver Robot, using Artificial Intelligence with Arduino</a></p>
<p></p>
<p></p>
<p>Espero que esse trabalho possa contribuir para que outras pessoas possam aprender mais sobre eletrônica, robôs, Arduino, etc.</p>
<p>Um abraço e até o próximo post!</p>
<p>Obrigado</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598953?profile=original" target="_self"><img width="250" src="http://storage.ning.com/topology/rest/1.0/file/get/1979598953?profile=RESIZE_320x320" width="250" class="align-full"/></a></p>Tutorial: Robô seguidor de linha com controle PID e ajustes por aplicativo Androidtag:labdegaragem.com,2016-04-20:6223006:BlogPost:5280902016-04-20T11:00:00.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<h4><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979594059?profile=original" target="_self"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979594059?profile=RESIZE_1024x1024" width="750"></img></a></h4>
<h4><br class="Apple-interchange-newline"></br>INTRODUÇÃO:</h4>
<p>O objetivo deste projeto é construir um robô seguidor de linha com controle PID. Também usaremos um dispositivo Android para mais facilmente poder configurar os principais parâmetros (ganhos) da malha de controle.</p>
<p>Abaixo um vídeo que mostra o robô a seguindo um circuito básico:…</p>
<p></p>
<h4><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979594059?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979594059?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></h4>
<h4><br class="Apple-interchange-newline"/>INTRODUÇÃO:</h4>
<p>O objetivo deste projeto é construir um robô seguidor de linha com controle PID. Também usaremos um dispositivo Android para mais facilmente poder configurar os principais parâmetros (ganhos) da malha de controle.</p>
<p>Abaixo um vídeo que mostra o robô a seguindo um circuito básico:</p>
<p><span><a href="https://youtu.be/z8Ldsf3Xnt4">https://youtu.be/z8Ldsf3Xnt4</a></span></p>
<p></p>
<h4>LISTA DE MATERIAIS:</h4>
<p>A lista de materiais necessários é muito simples e o robô final é muito barato (cerca de US$ 75,00):</p>
<ul>
<li>Corpo (pode ser adaptado para as suas necessidades):<ul>
<li>2 quadrados de madeira (80x80mm)</li>
<li>3 Grampos de papel</li>
<li>2 rodas de madeira (diâmetro: 50 mm)</li>
<li>1 roda “solta” (Caster)</li>
<li>9 Elásticos</li>
<li>Fita 3M “Command”</li>
<li>Articulações plásticas para fixação do sensor</li>
</ul>
</li>
<li>Protoboard e fiação</li>
<li>2 conjuntos de baterias (4XNi-metal hidreto) – 5V cada conjunto</li>
<li>2 Servos de Rotação Contínua (SM-S4303R)</li>
<li>Arduino Nano</li>
<li>Módulo Bluetooth HC-06</li>
<li>5 sensores x Linha (TCRT5000 4CH Infrared Linha Pista Seguidor Módulo Sensor + 1 sensor de Pista independente)</li>
<li>1 LED</li>
<li>1 Botão</li>
</ul>
<p></p>
<h4>AJUSTE DOS MOTORES</h4>
<p>Para os 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).</p>
<p><img class="alignnone size-full wp-image-2111" src="https://mjrobot.files.wordpress.com/2016/03/arduino3.png?w=840" alt="Arduino3"/></p>
<p>Olhando em detalhes:</p>
<ul>
<li>Um pulso de 1.5ms comandará o servo para que fique em sua posição neutra, ou “parado”.</li>
<li>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.</li>
<li>Pulsos entre 1.0 e 1.5ms ou 1.5ms e 2.0ms, farão os servos girarem em velocidades intermediárias e proporcionais.</li>
</ul>
<p><img class=" size-full wp-image-2112 alignright" src="https://mjrobot.files.wordpress.com/2016/03/arduino4.png?w=840" alt="Arduino4"/></p>
<p> </p>
<p>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.</p>
<p>Monte o Arduino e os servos como mostrado abaixo:</p>
<p><img class="alignnone wp-image-2732" src="https://mjrobot.files.wordpress.com/2016/04/motor.png?w=211&h=199" alt="Motor" width="211" height="199"/><img class=" wp-image-2745 alignnone" src="https://mjrobot.files.wordpress.com/2016/04/flb5wsqin3edek6-large.jpg?w=152&h=203" alt="flb5wsqin3edek6-large" width="152" height="203"/></p>
<p>O código abaixo, para o Arduino deve ser usado para o ajuste:</p>
<p></p>
<p><em>#include Servo // este código linha deve ser mudado, por favor, olhe o código anexado</em><br/> <em>Servo leftServo;</em><br/> <em>Servo rightServo;</em><br/> <em>void setup ()</em><br/> <em>{</em><br/><em> leftServo.attach (5);</em><br/><em> rightServo.attach (3);</em><br/><em> leftServo.writeMicroseconds (1500);</em><br/><em> rightServo.writeMicroseconds (1500);</em><br/> <em>}</em></p>
<p><em>void loop ()</em><br/> <em>{</em><br/> <em>}</em></p>
<p></p>
<h4>MONTAGEM DO CORPO E MOTORES PARA TESTE DE MOVIMENTO</h4>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/fk1e3mein3ef60l-medium.jpg?w=283&h=212" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/fk1e3mein3ef60l-medium.jpg?w=283&h=212&width=283" width="268" class="align-left" height="201"/></a> </p>
<p>1. Com a fita 3M Command, fixar os 2 Servos à uma das peças de madeira quadrado.</p>
<p> </p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/fd75kabin3ef63f-small.jpg?w=277&h=208" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/fd75kabin3ef63f-small.jpg?w=277&h=208&width=277" width="252" class="align-right" height="188"/></a>2. Fixar o segundo quadrado de madeira ao anterior, utilizando os grampos de papel. Ajuste o comprimento da plataforma para suas necessidades.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/fb16lqlin3ef65n-small.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/fb16lqlin3ef65n-small.jpg?w=840" class="align-left" width="283" height="212"/></a></p>
<p> </p>
<p> </p>
<p>3. Fixe o caster utilizando-se o grampo de papel.</p>
<p> </p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/ftmc0s8in3ee81d-medium.jpg?w=217&h=212" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/ftmc0s8in3ee81d-medium.jpg?w=217&h=212&width=217" width="217" class="align-right"/></a>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.</p>
<p> </p>
<p> </p>
<p><br/> 5. Conecte a bateria a ser utilizada com os servos: deixe uma linha de alimentação lateral do protoboard exclusivamente para os servos</p>
<p>6. Conecte o Arduino Nano ao protoboard</p>
<p>7. Conecte os terras do Protoboard ao GND do Arduino.</p>
<p>8. Conecte os Servos ao Arduino: LEFT => Pin 5; RIGHT => Pin 3</p>
<p>9. Ligue o LED ao Arduino Pino 13</p>
<p>10. Ligue o botão para Arduino Pin 9</p>
<p> </p>
<p>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:</p>
<ul>
<li>RIGHT Servo: velocidade de avanço frontal vai de 1500us (parado) a 2000us (velocidade máxima)</li>
<li>LEFT Servo: velocidade de avanço frontal vai de 1500us (parado) a 1000us (velocidade máxima)</li>
</ul>
<p>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).</p>
<p></p>
<p>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.<br/> Por exemplo:</p>
<p><em>while (digitalRead (buttonPin)) {}</em><br/> <em> motorTurn (LEFT, 500);</em><br/> <em> motorTurn (RIGHT, 500);</em></p>
<p>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”.</p>
<p>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.</p>
<p></p>
<h4>INSTALANDO O MÓDULO BLUETOOTH (OPCIONAL)</h4>
<p>O módulo Bluetooth HC-06 deverá ser instalado no protoboard. A biblioteca SoftSerial do Arduino será utilizada.</p>
<p><img class=" wp-image-2733 alignleft" src="https://mjrobot.files.wordpress.com/2016/04/motorbt.png?w=327&h=321" alt="Motor&amp;BT" width="327" height="321"/><img class=" wp-image-2878 alignright" src="https://mjrobot.files.wordpress.com/2016/04/f4fe9iqin3eedct-medium.jpg?w=216&h=306" alt="f4fe9iqin3eedct-medium" width="216" height="306"/></p>
<p>Abaixo as conexões de pino HC-06:</p>
<ul>
<li>Tx Pin para Arduino pino 10 (Rx)</li>
<li>RX Pin para Arduino pino 11 (Tx)</li>
<li>VCC / GND para Arduino 5V / GND</li>
</ul>
<p> </p>
<p>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.</p>
<p></p>
<h4>ADICIONANDO OS SENSORES DE LINHA</h4>
<p><br/> <img class=" wp-image-2885 alignleft" src="https://mjrobot.files.wordpress.com/2016/04/fqq0sfhin3ees26-large.jpg?w=243&h=182" alt="fqq0sfhin3ees26-large" width="268" height="201"/></p>
<p>1. Fixe os 5 sensores em uma barra de plástico, como mostrado nas fotos</p>
<p> </p>
<p><img class=" wp-image-2889 alignright" src="https://mjrobot.files.wordpress.com/2016/04/fw9zenoin3eeqyx-large.jpg?w=259&h=194" alt="fw9zenoin3eeqyx-large" width="268" height="201"/></p>
<p>2. É aconselhável para rotular os sensores para fins de teste. O nome sensores vai de de “0” (mais à esquerda) para “4” (mais à direita)</p>
<p> </p>
<p><img class=" wp-image-2894 alignleft" src="https://mjrobot.files.wordpress.com/2016/04/f9d55psin3eer0w-large.jpg?w=267&h=200" alt="f9d55psin3eer0w-large" width="268" height="201"/></p>
<p>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.</p>
<p> </p>
<p><img class=" wp-image-2899 alignright" src="https://mjrobot.files.wordpress.com/2016/04/f5c3vfgin3eersy-large.jpg?w=319&h=239" alt="f5c3vfgin3eersy-large" width="268" height="201"/></p>
<p>4. Conecte os cabos de pinos do Arduino, como abaixo:</p>
<ul>
<li>Sensor 0 = 12</li>
<li>Sensor 1 = 18</li>
<li>Sensor 2 = 17</li>
<li>Sensor 3 = 16</li>
<li>Sensor 4 = 19</li>
</ul>
<p></p>
<p><img class=" wp-image-2910 alignleft" src="https://mjrobot.files.wordpress.com/2016/04/fmhzshlin3ecx2e-large.jpg?w=274&h=204" alt="fmhzshlin3ecx2e-large" width="274" height="204"/></p>
<p>5. Fixe o segundo conjunto de baterias 5V e conecte ao pino Vin do Arduino.</p>
<p></p>
<p><img class=" wp-image-2730 alignright" src="https://mjrobot.files.wordpress.com/2016/04/line-follow-full-circuit.png?w=344&h=420" alt="Line Follow full circuit" width="344" height="420"/></p>
<p>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.</p>
<p></p>
<p> </p>
<h4>IMPLEMENTANDO A LÓGICA DOS SENSORES DE LINHA</h4>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/irsensor.jpg?w=840" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/irsensor.jpg?w=840" class="align-center"/></a>Cada 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.</p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/track-sensors.jpg?w=203&h=135" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/track-sensors.jpg?w=203&h=135&width=203" width="203" class="align-left"/></a>No 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 é con<a href="https://mjrobot.files.wordpress.com/2016/04/line-follower-sensor.png?w=80&h=78" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/line-follower-sensor.png?w=80&h=78&width=80" width="80" class="align-right"/></a>siderada “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.</p>
<p></p>
<p></p>
<p><img src="https://mjrobot.files.wordpress.com/2016/04/sensor1_cover.png?w=212&h=187&width=212" width="212" class="align-left"/></p>
<p>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”.</p>
<p> </p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/sensor1_2_cover.png?w=206&h=185" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/sensor1_2_cover.png?w=206&h=185&width=206" width="206" class="align-right"/></a></p>
<p></p>
<p></p>
<p>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).</p>
<p> </p>
<p></p>
<p>As possíveis combinações de saída do conjunto de sensores são:</p>
<ul>
<li>0 0 0 0 1</li>
<li>0 0 0 1 1</li>
<li>0 1 0 0 0</li>
<li>0 1 0 1 0</li>
<li>0 1 0 0 0</li>
<li>0 1 1 0 0</li>
<li>0 1 0 0 0</li>
<li>1 1 0 0 0</li>
<li>1 0 0 0 0</li>
</ul>
<p></p>
<p>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:</p>
<p>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”.</p>
<p>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.<br/> A variável de erro, relacionada com o estado do sensor será:</p>
<ul>
<li>0 0 0 0 1 ==> erro = 4</li>
<li>0 0 0 1 1 ==> erro = 3</li>
<li>0 0 0 1 0 ==> erro = 2</li>
<li>0 0 1 1 0 ==> erro = 1</li>
<li>0 0 1 0 0 ==> erro = 0</li>
<li>0 1 1 0 0 ==> erro = -1</li>
<li>0 1 0 0 0 ==> erro = -2</li>
<li>1 1 0 0 0 ==> erro = -3</li>
<li>1 0 0 0 0 ==> erro = -4</li>
</ul>
<p>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”):</p>
<p></p>
<p><em>const int lineFollowSensor0 = 12;</em></p>
<p><em>const int lineFollowSensor1 = 18;</em></p>
<p><em>const int lineFollowSensor2 = 17;</em></p>
<p><em>const int lineFollowSensor3 = 16;</em></p>
<p><em>const int lineFollowSensor4 = 19;</em></p>
<p></p>
<p>A fim de armazenar os valores de cada um dos sensores uma variável tipo Array será criada:</p>
<p></p>
<p><em>int LFSensor [5] = {0, 0, 0, 0, 0};</em></p>
<p></p>
<p>Cada posição da matriz irá ser constantemente actualizada com a saída de cada um dos sensores:</p>
<p></p>
<p><em>LFSensor [0] = digitalRead (lineFollowSensor0);</em></p>
<p><em>LFSensor [1] = digitalRead (lineFollowSensor1);</em></p>
<p><em>LFSensor [2] = digitalRead (lineFollowSensor2);</em></p>
<p><em>LFSensor [3] = digitalRead (lineFollowSensor3);</em></p>
<p><em>LFSensor [4] = digitalRead (lineFollowSensor4);</em></p>
<p></p>
<p>Uma vez armazenado o valor de cada um dos sensores, uma lógica deve ser implementada para gerar a variável de erro:</p>
<p><em>if (( LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 1 )) erro = 4;</em></p>
<p><em>else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 1) && (LFSensor [4] == 1)) erro = 3;</em></p>
<p><em>else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 1) && (LFSensor [4] == 0)) erro = 2;</em></p>
<p><em>else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 1) && (LFSensor [3] == 1) && (LFSensor [4] == 0)) erro = 1;</em></p>
<p><em>else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 1) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = 0;</em></p>
<p><em>else if ((LFSensor [0] == 0) && (LFSensor [1] == 1) && (LFSensor [2] == 1) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = - 1;</em></p>
<p><em>else if ((LFSensor [0] == 0) && (LFSensor [1] == 1) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = -2;</em></p>
<p><em>else if ((LFSensor [0] == 1) && (LFSensor [1] == 1) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = -3;</em></p>
<p><em>else if ((LFSensor [0] == 1) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) erro = -4;</em></p>
<p></p>
<h4>CONTROLANDO A DIREÇÃO (PROPORCIONAL CONTROL – P)<br/> </h4>
<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.</p>
<p><img class="alignnone size-full wp-image-2736 below-entry-meta" src="https://mjrobot.files.wordpress.com/2016/04/pd-control.png?w=840" alt="PD Control"/><br/> 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:</p>
<p></p>
<p><em>rightServo.writeMicroseconds (1500 + iniMotorPower);</em></p>
<p><em>leftServo.writeMicroseconds (1500 - iniMotorPower);</em></p>
<p></p>
<p>Por exemplo, com iniMotorSpeed = 250, significa que "LEFT" Servo receberá pulsos de 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).</p>
<p>Suponha agora que o robô comece a derivar para a esquerda ( a “linha vai para a direita”), fazendo com que o sensor 3 também, 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:</p>
<p></p>
<p><em>rightServo.writeMicroseconds (1500 + iniMotorPower - erro); // Erro positivo: velocidade diminue leftServo.writeMicroseconds (1500 - iniMotorPower - erro); //Erro positivo: velocidade aumenta</em></p>
<p></p>
<p>A lógica acima é correcta, mas é fácil 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.</p>
<p>A função final para os motores será:</p>
<p></p>
<p><em>int Kp = 50;</em></p>
<p><em>rightServo.writeMicroseconds (1500 + iniMotorPower - Kp * erro);</em></p>
<p><em>leftServo.writeMicroseconds (1500 - iniMotorPower - Kp * erro);</em></p>
<p></p>
<p>Podemos resumir o que acontecerá com os motores, como mostrado abaixo:</p>
<ul>
<li>Array de Sensores: 0 0 1 0 0<ul>
<li>erro = 0</li>
<li>Servo direito: pulso = 1,750us</li>
<li>Servo esquerdo: pulso = 1,250us</li>
<li>(ambos os motores a mesma velocidade)</li>
</ul>
</li>
<li>Array de Sensores: 0 0 1 1 0<ul>
<li>erro = 1</li>
<li>Servo direito: pulso = 1,700us (mais lento)</li>
<li>Servo esquerdo: pulso = 1,200us (mais rápido)</li>
</ul>
</li>
</ul>
<p>Se a situação é o oposto e o robô vai para a direita, o erro seria “negativo” e a velocidade dos servos deve mudar:</p>
<ul>
<li>Array de Sensores: 0 0 1 0 0<ul>
<li>erro = 0</li>
<li>Servo direito: pulso = 1,750us</li>
<li>Servo esquerdo: pulso = 1,250us</li>
<li>(ambos os motores a mesma velocidade)</li>
</ul>
</li>
<li>Array de Sensores: 0 1 1 0 0<ul>
<li>erro = -1</li>
<li>Servo direito: pulso = 1,800us (mais rápido)</li>
<li>Servo esquerdo: pulso = 1,300us (mais lento)</li>
</ul>
</li>
</ul>
<p></p>
<p>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.</p>
<p></p>
<p></p>
<h4>CONTROLE PID<br/> </h4>
<p>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.</p>
<p>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.</p>
<p><img src="https://mjrobot.files.wordpress.com/2016/04/pid.png?w=840" class="align-right"/></p>
<p></p>
<p></p>
<p></p>
<p>Como o PID funciona?<br/> O sistema calcula o “erro” ou “desvio” da </p>
<p>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).</p>
<p></p>
<p>Para mais informações, acesse: <a href="http://en.wikipedia.org/wiki/PID_controller" target="_blank">http://en.wikipedia.org/wiki/PID_controller</a></p>
<p></p>
<p>Implementando PID</p>
<ol>
<li>erro (e):<br/> Este valor é igual à diferença entre o ponto de regulação e o valor actual da quantidade a ser controlada.<br/> 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</li>
<li>Termo Proporcional (P):<br/> Este termo é proporcional ao erro.<br/> P = error<br/> 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.</li>
<li>Termo Integral (I):<br/> Este termo é a soma de todos os valores de erro anterior.<br/> I = I + error<br/> 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.</li>
<li>Diferencial ou termo derivativo (D):<br/> Este termo é a diferença entre o erro instantâneo do ponto de ajuste, e o erro a partir do instante anterior.<br/> D = error – previousError<br/> 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”.</li>
</ol>
<p></p>
<p>Equação:</p>
<pre>PIDvalue = (Kp * P) + (Ki * I) + (Kd * D)</pre>
<p></p>
<p>Onde:</p>
<ul>
<li>Kp é a constante usada para fazer variar a magnitude da mudança necessária para atingir o ponto de ajuste.</li>
<li>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.</li>
<li>Kd é a constante utilizada para variar a estabilidade do sistema.</li>
</ul>
<p>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.</p>
<p>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.</p>
<p>Com base na abordagem anterior, implementamos a função abaixo:</p>
<p></p>
<p><em>void calculatePID ()</em></p>
<p><em>{</em></p>
<p><em> P = error;</em></p>
<p><em> I = I + error;</em></p>
<p><em> D = error - previousError;</em></p>
<p><em> PIDvalue = (Kp * P) + (Ki * I) + (Kd * D);</em></p>
<p><em> previousError = error;</em></p>
<p><em>}</em></p>
<p></p>
<p>A constante Kp simples usada na última etapa será substituída agora por PIDvalue, mais completa:</p>
<p></p>
<p><em>void motorPIDcontrol ()</em></p>
<p><em>{</em></p>
<p><em> int leftMotorSpeed = 1500 - iniMotorPower - PIDvalue;</em></p>
<p><em> int rightMotorSpeed = 1500 + iniMotorPower - PIDvalue;</em></p>
<p><em> leftServo.writeMicroseconds (leftMotorSpeed);</em></p>
<p><em> rightServo.writeMicroseconds (rightMotorSpeed);</em></p>
<p><em>}</em></p>
<p></p>
<p>Mas note que se você tem Kd e Ki = 0, PIDvalue = Kp * error, exatamente como na etapa anterior onde usamos só o controle Proporcional.</p>
<p></p>
<p></p>
<h4>ADICIONANDO CONDIÇÕES ESPECIAIS AO CÓDIGO FINAL</h4>
<p><img class="alignnone size-full wp-image-3185" src="https://mjrobot.files.wordpress.com/2016/04/fmfsfcdin3ed6pp-medium.jpg?w=840" alt="fmfsfcdin3ed6pp-medium"/></p>
<p>Neste ponto do projeto, o robô já pode seguir sem parar um circuito de linha do tipo “loop constante”.</p>
<p></p>
<p>A função Loop do programa de ciclo seria simplesmente:</p>
<p></p>
<p><em>void loop ()</em></p>
<p><em>{</em></p>
<p><em> readLFSsensors (); // Ler sensores, armazenar os valores no Array de sensores e calcular o "erro"</em></p>
<p><em> calculatePID ();</em></p>
<p><em> motorPIDcontrol ();</em></p>
<p><em>}</em></p>
<p></p>
<p>Mas, para uma operação mais completa e real, é importante acrescentar, pelo menos um par de “comandos básicos de linha”.</p>
<pre>Por exemplo, vamos introduzir uma nova variável: "mode", definindo 3 estados para esta variável: </pre>
<p></p>
<p><em>#define STOPPED 0</em> <br/> <em>#define FOLLOWING_LINE 1</em> <br/> <em>#define NO_LINE 2</em></p>
<p></p>
<p>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”.</p>
<p></p>
<p><em>if ((LFSensor [0] == 1) && (LFSensor [1] == 1) && (LFSensor [2] == 1) && (LFSensor [3] == 1) && (LFSensor [4] == 1 )) {mode = STOPPED;}</em></p>
<p></p>
<p>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.</p>
<p></p>
<p><em>else if ((LFSensor [0] == 0) && (LFSensor [1] == 0) && (LFSensor [2] == 0) && (LFSensor [3] == 0) && (LFSensor [4] == 0)) {mode = NO_LINE;)</em></p>
<p></p>
<p>A função loop completa seria:</p>
<p></p>
<p><em>void loop ()</em></p>
<p><em>{</em></p>
<p><em> readLFSsensors ();</em></p>
<p><em> switch (mode)</em></p>
<p><em> {</em></p>
<p><em> case STOPPED:</em></p>
<p><em> motorStop();</em></p>
<p><em> break;</em></p>
<p><em> case NO_LINE:</em></p>
<p><em> motorStop ();</em></p>
<p><em> motorTurn (LEFT, 180);</em></p>
<p><em> break;</em></p>
<p><em> case FOLLOWING_LINE:</em></p>
<p><em> calculatePID ();</em></p>
<p><em> motorPIDcontrol ();</em></p>
<p><em> break;</em></p>
<p><em> }</em></p>
<p><em>}</em></p>
<p></p>
<p>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.</p>
<p></p>
<p></p>
<h4>USANDO O APP ANDROID PARA AJUSTAR OS GANHOS DO CONTROLADOR PID</h4>
<p>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.</p>
<p></p>
<p><em>float Kp = 50;</em></p>
<p><em>float Ki = 0;</em></p>
<p><em>float Kd = 0;</em></p>
<p></p>
<p>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.</p>
<p></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/picture1.png?w=109&h=106" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/picture1.png?w=109&h=106&width=109" width="109" class="align-left"/></a></p>
<p></p>
<p></p>
<p>Eu desenvolvi um aplicativo Android exclusivamente para isso:</p>
<p>o MJRoBot Line Follower PID Control</p>
<p></p>
<p></p>
<p></p>
<p></p>
<p>Em resumo o aplicativo possui:</p>
<p><img src="https://mjrobot.files.wordpress.com/2016/04/fkhjj4uin699t7j-medium.jpg?w=310&h=175&width=310" width="310" class="align-right"/></p>
<ul>
<li>Comandos manuais tradicionais:<ul>
<li>FW, BW, esquerda, direita e parar onde o aplicativo irá enviar ao módulo BT HC-o6, respectivamente: ‘f’, ‘b’, ‘l’, ‘r’ e ‘s’.</li>
</ul>
</li>
</ul>
<p> </p>
<p></p>
<p></p>
<p></p>
<p></p>
<p><a href="https://mjrobot.files.wordpress.com/2016/04/fpjpy8zin699t7l-medium.jpg?w=322&h=181" target="_blank"><img src="https://mjrobot.files.wordpress.com/2016/04/fpjpy8zin699t7l-medium.jpg?w=322&h=181&width=322" width="322" class="align-left"/></a></p>
<ul>
<li> 3sliders , um para cada constantes PID:<ul>
<li>Kp: “p / XXX”</li>
<li>Ki: “i / XXX”</li>
<li>Kd: “d / XXX”<ul>
<li>Em que “XXX” é um número de 0 a 100.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p> </p>
<ul>
<li>Um botão extra (“Play”) que vai funcionar exatamente como o botão ligado no pino 9 do Arduino. Você pode usar um ou o outro, não importa.</li>
</ul>
<p></p>
<p></p>
<p>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.</p>
<ul>
<li>MJRoBot_Line_Follower_PID_Control.aia</li>
<li>MJRoBot_Line_Follower_PID_Control.apk</li>
</ul>
<p></p>
<h4>ALTERAR O CÓDIGO PARA O AJUSTE REMOTO DOS GANHOS DO PID</h4>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979595794?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979595794?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<p>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. </p>
<p>No vídeo, você pode ver alguns testes usando o App Android:</p>
<p><a href="https://www.youtube.com/watch?v=0iU2szk9UdY" target="_blank">Video Robô seguidor de linha</a></p>
<p></p>
<p>Abaixo o código final para o robô:</p>
<h4><a href="https://www.dropbox.com/sh/epsvn2tx2bq10xk/AAD67lZ1b7rBytQqWtJJaONNa?dl=0">ARDUINO & ANDROID CODES</a></h4>
<p></p>
<p></p>
<h4>CONCLUSÃO<br/> </h4>
<p>Este é o primeiro tutorial de um projeto mais complexo, explorando a potencialidade de um robô seguidor de linha. No próximo tutorial, desenvolverei um robô com habilidade para resolver um labirinto, ou seja não só encontrar o caminho de saída, mas também qual seria o caminho mais curto e rápido.</p>
<p></p>
<p>Aproveito também a pedir a vocês, amigos garagistas que façam uma visita a meu post no Instructables.com abaixo e se gostarem, que votem no tutorial, que está concorrendo ao "Contest Robotics" (é só clicar na bandeirinha laranja no canto superior direito da página). Muito Obrigado. </p>
<p></p>
<p><a href="http://www.instructables.com/id/Line-Follower-Robot-PID-Control-Android-Setup/" target="_blank">Votar em: Line Follower Robot - PID Control - Android Setup</a></p>
<p></p>
<p>Espero que esse trabalho possa contribuir para que outras pessoas possam aprender mais sobre eletrônica, robôs, Arduino, etc.</p>
<p></p>
<p>Um abraço e até o próximo post!<br/> Obrigado</p>Projeto: MJRoBot I – O Robot de Berkeley - Passos para a construção de um robot autônomo.tag:labdegaragem.com,2016-04-04:6223006:BlogPost:5244332016-04-04T12:51:04.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<div class="entry-summary"><p><img class="align-center" src="https://mjrobot.files.wordpress.com/2016/01/mjrobot-i.jpg?w=840"></img></p>
<p></p>
</div>
<div class="post-thumbnail"></div>
<div class="entry-content"><p>Fazem alguns meses, terminei meu primeiro curso on-line. Foi uma experiência nova mas que despertou em mim uma paixão antiga a muito adormecida, a eletrônica! De lá para cá, fiz vários outros cursos, mas como o primeiro a gente nunca esquece……..</p>
<p>O curso foi: …</p>
</div>
<div class="entry-summary"><p><img src="https://mjrobot.files.wordpress.com/2016/01/mjrobot-i.jpg?w=840" class="align-center"/></p>
<p></p>
</div>
<div class="post-thumbnail"></div>
<div class="entry-content"><p>Fazem alguns meses, terminei meu primeiro curso on-line. Foi uma experiência nova mas que despertou em mim uma paixão antiga a muito adormecida, a eletrônica! De lá para cá, fiz vários outros cursos, mas como o primeiro a gente nunca esquece……..</p>
<p>O curso foi: <a href="https://www.edx.org/course/electronic-interfaces-bridging-physical-uc-berkeleyx-ee40lx-0" target="_blank">EE40LX: Electronic Interfaces,</a> através da plataforma EDX e ministrado pela Berkeley University, da California. A idéia foi uma revisão geral de eletrônica básica através de exercícios e experimentos, culminando em um Robot que obedecesse alguns requisitos básicos:</p>
<ul>
<li>O robot deveria no mínimo:<ul>
<li>Responder a luz</li>
<li>Produzir som</li>
<li>Responder ao som</li>
<li>Mover motores</li>
</ul>
</li>
<li>Adicionalmente, incorporei ao projeto:<ul>
<li>Produzir luz</li>
<li>Responder remotamente a comandos IR</li>
</ul>
</li>
</ul>
<p>A foto mostra o monstrengo final…..</p>
<p>Para ser aprovado, entreguei o vídeo abaixo aonde demonstro que o robot cumpria as especificações do curso:</p>
<div class="jetpack-video-wrapper"><a href="https://youtu.be/BOx-9IIPbL4">https://youtu.be/BOx-9IIPbL4</a></div>
<div class="jetpack-video-wrapper"><h3>A lista de materiais:</h3>
</div>
<div class="jetpack-video-wrapper"></div>
<p>Para a construção do robot, utilizei a lista de componentes abaixo:</p>
<p><img class="alignnone size-full wp-image-131" src="https://mjrobot.files.wordpress.com/2016/01/photo-1-11-16-18-47-23.png?w=840" alt="Photo 1-11-16, 18 47 23"/></p>
<p>Para o coração (ou melhor, o cerebro….) do robot, utilizei o Arduino UNO. abaixo o diagrama de blocos com as respectivas pinagens. Para um projeto mais elaborado é fundamental desenvolver este tipo de diagrama. Ele vai sempre ser a guia a que se tem que recorrer durante a codificação do SW.</p>
<p><img class="alignnone size-full wp-image-139" src="https://mjrobot.files.wordpress.com/2016/01/photo-1-11-16-18-46-08.png?w=840" alt="Photo 1-11-16, 18 46 08"/></p>
<h3>O Hardware:</h3>
<h4>“RESPOSTA A LUZ”</h4>
<p>A base da “reação a luz”, foram as fotocélulas. As fotocélulas (que são resistores que variam com a luz), foram conectados na configuração “ponte de Whitestone”. Isso fazia que uma variação na intensidade de luz provocasse um desequilíbrio da ponte resistiva, o que levava a saturação de um amplificador operacional. Meio enrolado, mas muito inteligente (não eu, mas os caras de Berkley que sugeriram a solução</p>
<p><img class="alignnone size-full wp-image-152" src="https://mjrobot.files.wordpress.com/2016/01/photo-1-11-16-18-48-11.png?w=840" alt="Photo 1-11-16, 18 48 11"/></p>
<p>Outra sacada muito legal, foi o uso de um “Power Block”, ou seja, ao invés de deixar a ponte constantemente alimentada (importante lembrar que em um robot autônomo, bateria é vida!), se alimenta a mesma via um pino de saída do Arduino. Assim, somente quando se necessita verificar se o sensor tem luz ou não, 5V é produzido pelo Arduino, alimentando momentaneamente a ponte durante a leitura (no caso, o pino 8).</p>
<p>Foram utilizadas duas fotocelulas, uma frontal e uma traseira. A ação é simples, quando o robot de desloca para a frente e a luz é interrompida, os motores dão “marcha-ré”. E obviamente, vice-e-versa.</p>
<p> </p>
<h4>“GERAÇÃO E RESPOSTA A SOM”</h4>
<p>Para que o robot pudesse “ouvir”, um velho e bom microfone de PC foi o escolhido. Como o sinal do microfone é muito baixo, um Amplificador Operacional inversor foi utilizado para amplificação do sinal. Também antes de ser amplificado, o sinal de som passou por um filtro passa altas, eliminando-se assim a componente DC.</p>
<p>Para “falar”, foi utilizado um simples “buzzer”.</p>
<p><img class="alignnone size-full wp-image-153" src="https://mjrobot.files.wordpress.com/2016/01/photo-1-11-16-18-48-00.png?w=840" alt="Photo 1-11-16, 18 48 00"/></p>
<h4>“MOVER MOTORES”</h4>
<p>Para o movimento dos motores uma Ponte H, a velha e boa L293D foi a escolhida. Importante não esquecer de adicionar uns capacitores cerâmicos nos terminais do motor. Isto ajudará a diminuir eventuais ruídos elétricos produzidos pelas “escovas” dos motores DC (10pF está bem). Ah! falando em ruído, nunca é demais lembrar que sempre é bom alimentar os motores com uma batería separada da usada pelo Arduíno (não se esquecendo de conectar os “terras”).<img class="alignnone size-full wp-image-154" src="https://mjrobot.files.wordpress.com/2016/01/photo-1-11-16-18-48-21.png?w=840" alt="Photo 1-11-16, 18 48 21"/></p>
<p>Para sinalização, utilizei um LED RGB catodo comum. Com isso, podia acompanhar algumas ações do robot através dos LEDs.</p>
<p>Para receber comandos via um controle remoto IR (Infra vermelho), utilizei um VS1838b. É um sensor con tres terminais, VCC, GND e Signal. Um sensor simples e bem confiável.</p>
<p>Juntando tudo fica uma massaroca mais ou menos assim:</p>
<p><img class="alignnone size-full wp-image-155" src="https://mjrobot.files.wordpress.com/2016/01/photo-9-13-15-21-05-28.jpg?w=840" alt="Photo 9-13-15, 21 05 28"/></p>
<h3>O Software:</h3>
<p>A idéia do SW foi bem simples. Ao ser ligado, o robot gerava 4 bips, ficando a espera do sinal “ON” proveniente do controle remoto. Ao receber-lo, soavam 2 bips, o LED ficava azul e o robot estava pronto para receber um comando de voz. No caso um simples ruído mais pronunciado como um assovio ou uma palma (o ganho do Amp Op, deve ser testado para gerar um sinal coerente). Também é importante que durante a faze de “set-up”, se “escute” o nível de ruído do ambiente, assim consegue-se uma melhor precisão e o robot não parte com qualquer barulhinho.</p>
<p>Com o comando de som, o robot começava a mover-se para a frente (LED ficava verde) até que o sensor de luz frontal fosse bloqueado. Nesse momento, o LED ficava vermelho e o robot passava a mover-se de “marcha-ré”, até que o sensor de luz traseiro fosse bloqueado, invertendo-se assim o movimento. O robot ficava nesse zigue-zague até receber um comando para parar (controle remoto), ou até que o “piloto” dormisse de tédio fazendo o monstrengo se arrebentar no chão (é, o teste foi em cima de uma mesa…..).</p>
<p>Abaixo, o fluxo do programa (dá para entender melhor que o meu Bla-bla-bla anterior):</p>
<p><img class="alignnone size-full wp-image-157" src="https://mjrobot.files.wordpress.com/2016/01/photo-1-11-16-18-46-31.png?w=840" alt="Photo 1-11-16, 18 46 31"/></p>
<p>O codigo final do robot pode ser baixado de meu Dropbox público:</p>
<p><a href="https://www.dropbox.com/sh/246l6yksl6fj0uw/AACsVcKSg5yIOohXSj6yuL63a?dl=0" rel="nofollow">https://www.dropbox.com/sh/246l6yksl6fj0uw/AACsVcKSg5yIOohXSj6yuL63a?dl=0</a></p>
<p>That’s all Folks! Apenas um minuto de silencio para o velho e bom MJRoBot I, que hoje descansa em paz em minha gaveta de componentes e serve de partes para seu irmão mais novo (ou filho?), o MJR0Bot II!!!!!!! que aparecerá em uma nova entrada deste Blog.</p>
<p>Para matar a saudade fica umas fotinhos para lembrar a construção do rapaz!</p>
<p><img class="alignnone size-full wp-image-158" src="https://mjrobot.files.wordpress.com/2016/01/photo-1-11-16-18-49-06.png?w=840" alt="Photo 1-11-16, 18 49 06"/></p>
<p></p>
<p class="p1">Para mais projetos e tutoriais, por favor, visite meu Blog: <a href="http://mjrobot.org/">http://mjrobot.org/</a></p>
<p class="p1"></p>
<p class="p1"></p>
<p class="p1"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596245?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979596245?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<p class="p1"></p>
<p class="p1">Obrigado e espero que este projeto possa ajudar a outros iniciantes no campo da eletrônica a aprender sobre o Arduino , robôs , eletrônica básica, etc.</p>
<p class="p1">Abração </p>
</div>Projeto: Protótipo de uma estação robótica móvel para captura de dados ambientaistag:labdegaragem.com,2016-03-23:6223006:BlogPost:5207942016-03-23T12:00:00.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<h5 class="p1"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979595446?profile=original" target="_self"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979595446?profile=original" width="467"></img></a></h5>
<h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">Descrição geral:</span></h5>
<p class="p1">A idéia deste projecto é o desenvolvimento de um protótipo totalmente funcional para uma estação móvel usada na coleta de dados ambientais tais como: temperatura, umidade e luminosidade. Este protótipo foi desenvolvido somente para fins didáticos e fez…</p>
<h5 class="p1"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979595446?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/1979595446?profile=original" width="467" class="align-full"/></a></h5>
<h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">Descrição geral:</span></h5>
<p class="p1">A idéia deste projecto é o desenvolvimento de um protótipo totalmente funcional para uma estação móvel usada na coleta de dados ambientais tais como: temperatura, umidade e luminosidade. Este protótipo foi desenvolvido somente para fins didáticos e fez parte de meu projeto final no curso de especialização do Coursera em parceria com a University of California, Irvine: “<a href="https://www.coursera.org/specializations/iot" target="_blank">Uma Introdução à Programação da Internet of Things (IOT)</a>“.</p>
<p class="p1"></p>
<h5 class="p1"><span class="font-size-5">Considerações do projeto:</span></h5>
<ul>
<li>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.</li>
<li class="p1">O usuário deve receber um feedback visual (streaming de vídeo ao vivo)</li>
<li class="p1">Os dados capturados serão analisados através de um site público (neste caso: thingspeak.com)</li>
<li class="p1">Os dados estarão disponíveis para os usuários em um formato gráfico e tabela</li>
<li class="p1">Alarmes via Twitter serão gerados localmente pela estação ou pelo website</li>
<li class="p1">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.</li>
</ul>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979597308?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979597308?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<h5><span class="font-size-5">Opções de projeto:</span></h5>
<p class="p1">Com base nos requisitos, inicialmente 2 opções foram consideradas para este projeto.</p>
<ol>
<li class="p1">Um único processador responsável por todas as tarefas, que neste caso deveria ser um Raspberry Pi.</li>
<li class="p1">Um processador dual , sendo as funções divididos entre eles ( Arduino e RPI ) :<ul>
<li class="p1">Processor 1: RPi<ul>
<li class="p1">Captura de dados</li>
<li class="p1">Comunicação com a Web</li>
<li class="p1">Transmissão de vídeo</li>
<li class="p1">Envío de mensagens via mídia social</li>
</ul>
</li>
<li class="p1">Processor 2: Arduino<ul>
<li class="p1">Controle dos motores (movimento e posicionamento da câmera)</li>
<li class="p1">Evasão de obstáculos</li>
<li class="p1">Comunicação com o controle remoto</li>
</ul>
</li>
</ul>
</li>
</ol>
<p class="p1">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.</p>
<p class="p1"></p>
<h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">A Lista de materiais:</span></h5>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979598764?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979598764?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<div class="entry-content"><h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">Instalação e testes da Camera (Pi-Cam) no RPi</span></h5>
<ol>
<li>Instale PIP<ul>
<li><em>sudo apt- get install python- pip</em></li>
</ul>
</li>
<li>Instalar a biblioteca picamera :<ul>
<li class="p1"><em>pip install picamera</em></li>
</ul>
</li>
<li class="p1">Instalar a biblioteca flask Python:<ul>
<li class="p1"><em>sudo pip install flask</em></li>
</ul>
</li>
<li class="p1">Baixar projeto de streaming de vídeo Flask:<ul>
<li class="p1"><em>git clone <a href="https://github.com/miguelgrinberg/flask-video-streaming.git">https://github.com/miguelgrinberg/flask-video-str …</a></em></li>
</ul>
</li>
<li class="p1">Na pasta do projeto editar o arquivo app.py , comente esta linha:<ul>
<li class="p1"><em>#from camera import Camera</em></li>
</ul>
</li>
<li class="p1"> Tirar o comentario da linha:<ul>
<li class="p1"><em>from camera_pi import Camera</em></li>
</ul>
</li>
<li class="p1">Salve o arquivo app.py</li>
<li class="p1">Executar <em>ifconfig</em> para descobrir o endereço IP local do seu Raspberry Pi “yourLocalIPaddress ” .</li>
<li class="p1">Inicie o servidor Flask executando este comando :<ul>
<li class="p1"><em>python app.py </em></li>
</ul>
</li>
<li class="p1">Uma mensagem será impressa no monitor:<ul>
<li class="p1">“running on “<a href="http://0.0.0.0:5000/">http://0.0.0.0.:5000/ </a>(press CTRL+C to quit)</li>
</ul>
</li>
<li class="p1">Abra um navegador e acesse este endereço :<ul>
<li class="p1">” YourLocalIPaddress ” : 5000</li>
</ul>
</li>
</ol>
<h5 class="p1"></h5>
<h5 class="p1"></h5>
<h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">Instalando o sensor de temperatura e humidade: HC-11</span></h5>
<p class="p1"><img class="size-full wp-image-2116 alignnone" src="https://mjrobot.files.wordpress.com/2016/03/dh11-rpi.png?w=840" alt="DH11-RPi"/><img class=" wp-image-2114 alignnone" src="https://mjrobot.files.wordpress.com/2016/03/dh11-rpi-hw.png?w=108&h=144" alt="DH11-RPi hw" width="108" height="144"/></p>
<ol>
<li class="p1">Em primeiro lugar, obter a Biblioteca do Github :<ul>
<li class="p1"><em>git clone<a href="https://github.com/adafruit/Adafruit_Python_DHT.git"> https: //github.com/adafruit/Adafruit_Python_DHT.g …</a></em></li>
</ul>
</li>
<li class="p1">Instalação da Biblioteca :<ul>
<li class="p1"><em>sudo apt-get update</em></li>
<li class="p1"><em>sudo apt- get install build-essential python -dev python- openssl</em></li>
<li class="p1"><em>cd / Home / Pi / Adafruit_Python_DHT</em></li>
<li class="p1"><em>sudo python setup.py install</em></li>
</ul>
</li>
<li class="p1">Teste o sensor, executando o programa: <em>AdafruitDHT.py</em> no monitor. Entre os parâmetros como : 11 ( sensor DHT11 ) e 4 ( GPIO onde o sensor está ligado )<ul>
<li class="p1"><em>sudo Python AdafruitDHT.py 11 4</em></li>
</ul>
</li>
<li class="p1">O resultado deve ser a temperatura ea humidade lido pelo sensor</li>
</ol>
<p><img class="alignnone size-full wp-image-2115" src="https://mjrobot.files.wordpress.com/2016/03/dh11-rpi-monitor.png?w=840" alt="DH11-RPi monitor"/></p>
<h5><span class="font-size-5">Enviando dados para a internet</span></h5>
<p class="p1">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:</p>
<p class="p1"><a href="http://electronut.in/dht11-rpi-cloud-plot/">Plotting DHT11 sensor data at ThingSpeak.com using Raspberry Pi</a></p>
<p class="p1">Passos:</p>
<ul>
<li class="p1">A definição de um canal em ThingSpeak.com :</li>
</ul>
<p><img class="alignnone size-full wp-image-2141" src="https://mjrobot.files.wordpress.com/2016/03/thinkspeak1.png?w=840" alt="ThinkSpeak1"/></p>
<ul>
<li class="p1">Execução do códigoPython para testes:<ul>
<li class="p1"><em>sudo Python temp_hum_test.py</em></li>
<li class="p1">NOTA: Todos os códigos fonte estão disponíveis ao final do post.</li>
</ul>
</li>
</ul>
<p class="p1"><img class="alignnone size-full wp-image-2142" src="https://mjrobot.files.wordpress.com/2016/03/thinkspeak2.png?w=840" alt="ThinkSpeak2"/></p>
<p class="p1"><img class="alignnone size-full wp-image-2143" src="https://mjrobot.files.wordpress.com/2016/03/thinkspeak3.png?w=840" alt="ThinkSpeak3"/></p>
<p></p>
</div>
<h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">Adicionando o sensor de luz:</span></h5>
<p class="p1">Um tutorial muito bom que serviu de base para esta parte do projeto, pode ser visto aqui:</p>
<p class="p1"></p>
<p class="p1"><a href="http://www.instructables.com/id/Build-Your-First-IOT-with-a-Raspberry-Pi-DHT11-sen/">Build Your First IOT with a Raspberry Pi, DHT11 sensor, and Thingspeak.</a></p>
<p class="p1">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).</p>
<ul>
<li class="p1">O Código Python utilizado neste teste:<ul>
<li class="p1"><em>sudo Python iot_temp_hum_light.py</em></li>
</ul>
</li>
</ul>
<p> </p>
<h5><span class="font-size-5">Adicionando um sensor para a intensidade de luz</span></h5>
<p><img class="alignnone wp-image-2131" src="https://mjrobot.files.wordpress.com/2016/03/rpi-sensors3.png?w=408&h=343" alt="RPi sensors3" width="408" height="343"/><img class=" wp-image-2130 alignnone" src="https://mjrobot.files.wordpress.com/2016/03/rpi-sensors2.png?w=156&h=149" alt="RPi sensors2" width="156" height="149"/></p>
<p class="p1">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).</p>
<p class="p1">O Código Python utilizado neste teste:</p>
<ul>
<li class="p1"><em>sudo Python iot_temp_hum_light_pot.py</em></li>
</ul>
<p><img class="alignnone wp-image-2132" src="https://mjrobot.files.wordpress.com/2016/03/rpi-sensors4.png?w=414&h=264" alt="RPi sensors4" width="414" height="264"/><img class=" wp-image-2133 alignnone" src="https://mjrobot.files.wordpress.com/2016/03/rpi-sensors5.png?w=255&h=300" alt="RPi sensors5" width="255" height="300"/><img class="alignnone size-full wp-image-2134" src="https://mjrobot.files.wordpress.com/2016/03/rpi-sensors6.png?w=840" alt="RPi sensors6"/></p>
<h5><span class="font-size-5">Enviando mensagens de alarm via Tweeter</span></h5>
<p class="p2">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) .</p>
<p class="p2">Abaixo um exemplo de código Python para o envío de tweets diretamente pelo RPi:</p>
<p>from twython import Twython <br/> C_KEY = "xxxxxxxxxxxx" <br/> C_SECRET = "yyyyyyyyy" <br/> A_TOKEN = "zzzzzzzzzzzz" <br/> A_SECRET = "wwwwwwwww"</p>
<p>api = Twython(C_KEY, C_SECRET, A_TOKEN, A_SECRET)</p>
<p>api.update_status(status="IoT Capstone Project - Tweet test")</p>
<pre><br/><br/>
</pre>
<p><img class=" wp-image-2144 alignleft" src="https://mjrobot.files.wordpress.com/2016/03/tweet1.png?w=353&h=95" alt="tweet1" width="353" height="95" style="white-space: normal;"/></p>
<p class="p2"></p>
<p class="p2"></p>
<p class="p2">Observe 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 .</p>
<p class="p2">Outra solução simples como explicado anteriormente, é enviar um Twitter diretamente do site. Neste caso, pode ser usado o recurso “React” de ThingSpeak.com .</p>
<p class="p2"><img class="alignnone size-full wp-image-2145" src="https://mjrobot.files.wordpress.com/2016/03/tweet2.png?w=840" alt="tweet2"/></p>
<p><img class=" wp-image-2146 alignnone" src="https://mjrobot.files.wordpress.com/2016/03/tweet3.png?w=351&h=118" alt="tweet3" width="351" height="118"/></p>
<h5 class="p1"></h5>
<p></p>
<h5 class="p1"><span class="font-size-5">Conectando o RPi e ao Arduino via port Serial</span></h5>
<p class="p1">O Arduino utilizado foi o NANO que é tão poderoso como a UNO, mas com um ” fator de forma” pequeno .</p>
<p class="p1"><img class="alignnone size-full wp-image-2135" src="https://mjrobot.files.wordpress.com/2016/03/rpi-ardu-serial-test.png?w=840" alt="RPi-Ardu-Serial-test"/></p>
<p class="p1">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”).</p>
<p><img class="alignnone size-full wp-image-2138" src="https://mjrobot.files.wordpress.com/2016/03/rpi-arduino3.png?w=840" alt="RPi-Arduino3"/></p>
<ul>
<li class="p1">Abaixo o código Arduino e Python utilizado nos testes :<ul>
<li class="p1"><em>sudo Python ardu_pi_serial.py</em></li>
</ul>
</li>
</ul>
<h5 class="p1"></h5>
<p></p>
<h5 class="p1"><span class="font-size-5">Enviando os dados do Arduino para a Web:</span></h5>
<p class="p1"><img class="alignnone size-full wp-image-2136" src="https://mjrobot.files.wordpress.com/2016/03/rpi-arduino1.png?w=840" alt="RPi-Arduino1"/></p>
<p class="p1"><img class=" wp-image-2137 alignleft" src="https://mjrobot.files.wordpress.com/2016/03/rpi-arduino2.png?w=295&h=221" alt="RPi-Arduino2" width="295" height="221"/></p>
<p class="p1">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 .</p>
<p class="p1">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) .</p>
<p><img class="alignnone size-full wp-image-2139" src="https://mjrobot.files.wordpress.com/2016/03/rpi-arduino4.png?w=840" alt="RPi-Arduino4"/></p>
<p><img class="alignnone size-full wp-image-2140" src="https://mjrobot.files.wordpress.com/2016/03/rpi-arduino5.png?w=840" alt="RPi-Arduino5"/></p>
<p>Abaixo o código Arduino e Python utilizado nos testes :</p>
<ul>
<li class="p1"><em>sudo iot_temp_hum_pot_ardu.py</em></li>
</ul>
<p> </p>
<p></p>
<h5><span class="font-size-5">Testando os motores do rover:</span></h5>
<p><img class="alignnone wp-image-2110" src="https://mjrobot.files.wordpress.com/2016/03/arduino2.png?w=284&h=214" alt="Arduino2" width="284" height="214"/></p>
<p class="p1">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.</p>
<p class="p1">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).</p>
<p class="p1"><img class=" wp-image-2111 alignleft" src="https://mjrobot.files.wordpress.com/2016/03/arduino3.png?w=319&h=182" alt="Arduino3" width="319" height="182"/></p>
<ul>
<li>Um pulso de 1.5ms vai posicionar o servo na posição neutra, ou “parado”.</li>
<li class="p1">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.</li>
<li class="p1">Pulsos entre 1.0 e 1.5ms ou 1.5ms e 2.0ms, gerarão velocidades intermediárias proporcionais.</li>
</ul>
<p class="p1"><img class=" wp-image-2112 alignleft" src="https://mjrobot.files.wordpress.com/2016/03/arduino4.png?w=104&h=143" alt="Arduino4" width="104" height="143"/>A 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.</p>
<p class="p1">Codigo para calibração dos servos:</p>
<p>#include <Servo.h><br/> Servo leftServo; <br/> Servo rightServo; <br/> Void setup() <br/> { <br/> leftServo.attach(6); <br/> rightServo.attach(5); <br/> leftServo.writeMicroseconds(1500); <br/> rightServo.writeMicroseconds(1500); <br/> } <br/> void loop() <br/> { <br/> }</p>
<pre><br/><br/>
</pre>
<p class="p1">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).</p>
<ul>
<li class="p1"><em>MotorCode.ino</em></li>
</ul>
<h5 class="p1"></h5>
<h5 class="p1"></h5>
<h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">Montagem da estrutura final do Rover e testes com o Controle Remoto/Bluetooth:</span></h5>
<p class="p2">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 .</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-2"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/remote-ctrl5/"><img src="https://mjrobot.files.wordpress.com/2016/03/remote-ctrl5.png?w=390&h=292&crop=1" width="390" height="292" title="Remote Ctrl5" alt="Remote Ctrl5"/></a></div>
<div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/remote-ctrl4/"><img src="https://mjrobot.files.wordpress.com/2016/03/remote-ctrl4.png?w=390&h=293&crop=1" width="390" height="293" title="Remote Ctrl4" alt="Remote Ctrl4"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/remote-ctrl3/"><img src="https://mjrobot.files.wordpress.com/2016/03/remote-ctrl3.png?w=442&h=589&crop=1" width="442" height="589" title="Remote Ctrl3" alt="Remote Ctrl3"/></a></div>
</div>
</div>
</div>
<p class="p1">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:</p>
<p class="p1"><a href="http://mjrobot.org/2016/01/30/conectando-coisas-atraves-do-bluetooth/">Conectando “coisas” com o Bluetooth</a></p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/remote-ctrl1/"><img src="https://mjrobot.files.wordpress.com/2016/03/remote-ctrl1.png?w=481&h=468&crop=1" width="481" height="468" title="Remote Ctrl1" alt="Remote Ctrl1"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/remote-ctrl2/"><img src="https://mjrobot.files.wordpress.com/2016/03/remote-ctrl2.png?w=351&h=468&crop=1" width="351" height="468" title="Remote Ctrl2" alt="Remote Ctrl2"/></a></div>
</div>
</div>
</div>
<p class="p1">O código Arduino completo ( o anterior + BT ) estão disponíveis no file abaixo (não se esqueça que são 3 arquivos que devem estar sempre dentro de uma mesma pasta) :</p>
<ul>
<li class="p1">Iot_Capstone_Robot_10mar16.ino</li>
</ul>
<p> </p>
<p></p>
<h5><span class="font-size-5">A App Android</span></h5>
<p>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 .</p>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/andoid-blocks/"><img src="https://mjrobot.files.wordpress.com/2016/03/andoid-blocks.png?w=497&h=516&crop=1" width="497" height="516" title="Andoid blocks" alt="Andoid blocks"/></a></div>
</div>
<div class="gallery-group images-2"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/andoid-desig1/"><img src="https://mjrobot.files.wordpress.com/2016/03/andoid-desig1.png?w=335&h=254&crop=1" width="335" height="254" title="Andoid desig1" alt="Andoid desig1"/></a></div>
<div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/andoid-desig2/"><img src="https://mjrobot.files.wordpress.com/2016/03/andoid-desig2.png?w=335&h=258&crop=1" width="335" height="258" title="Andoid desig2" alt="Andoid desig2"/></a></div>
</div>
</div>
</div>
<p class="p1">O aplicativo é muito simples. Ele possui:</p>
<ul>
<li class="p1">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.</li>
<li class="p1">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 )</li>
<li class="p1">Entrada do endereço IP da PiCam e um botão para armazená-lo.</li>
<li class="p1">Enviar / receber mensagens de texto para Arduino (o botão ” avião de papel ” é usado para enviar as mensagens)</li>
</ul>
<p class="p1">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.</p>
<p class="p1"><a href="https://www.dropbox.com/sh/oazz2h1mkzdoorq/AACab2lJ6UNFv0ijSjnqYj7pa?dl=0"><img class="alignnone wp-image-2128" src="https://mjrobot.files.wordpress.com/2016/03/rover-icon.png?w=125&h=126" alt="rover icon" width="125" height="126"/>App Android</a></p>
<h5 class="p1"></h5>
<h5 class="p1"></h5>
<h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">Os sensores para deteção de obstáculos:</span></h5>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/ultrasound-sensor2/"><img src="https://mjrobot.files.wordpress.com/2016/03/ultrasound-sensor2.png?w=408&h=306&crop=1" width="408" height="306" title="ultrasound sensor2" alt="ultrasound sensor2"/></a></div>
</div>
<div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/ultrasound-sensor1/"><img src="https://mjrobot.files.wordpress.com/2016/03/ultrasound-sensor1.png?w=424&h=306&crop=1" width="424" height="306" title="ultrasound sensor1" alt="ultrasound sensor1"/></a></div>
</div>
</div>
</div>
<p class="p1">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.</p>
<p class="p1">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 “<em>int distMeter ()</em>” é utilizado para este cálculo.</p>
<p class="p1">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.</p>
<p class="p1"><a href="https://youtu.be/whvcab0c9HQ" target="_blank">Vídeo de teste de obstáculos</a></p>
<p class="p1">O código completo Arduino (o anterior + desvio de obstáculos e procure servo controle ) está disponível nos arquivos:</p>
<ul>
<li><em>Iot_Capstone_Robot_BT_17mar16.ino</em></li>
</ul>
<h5 class="p1"></h5>
<h5 class="p1"></h5>
<h5 class="p1"></h5>
<h5 class="p1"><span class="font-size-5">Integração e testes finais:</span></h5>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979600910?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/1979600910?profile=original" width="471" class="align-full"/></a></p>
<ol>
<li>Em primeiro lugar, execute o programa python para ativar a Pi- Cam que deverá estar no diretório flask (verifique o link ao final para detalhes de instalação da camera) e verifique se a camera está enviando o video em streaming:<ul>
<li><em>sudo python app.py</em></li>
</ul>
</li>
<li>Uma vez que você pode ver o vídeo, execute um CTRL- C para libertar o monitor para introduzir o código Python principal:<ul>
<li><em>sudo iot_temp_hum_pot_ardu.py</em></li>
</ul>
</li>
<li><span>Verificar os valores dos sensores ( aquecer o sensor , cobrir o sensor de luz , etc. ). Veja o resultado no monitor e no site :</span><ul>
<li><em>sudo python iot_temp_hum_light_pot_ardu.py</em></li>
</ul>
</li>
<li>Execute o sketch final para o Arduino<ul>
<li><em>Iot_Capstone_Robot_BT_19mar16.ino</em></li>
</ul>
</li>
<li><span>Mova o rover com o aplicativo Android e confira o vídeo e os valores do sensor</span></li>
<li>Verifique se o rover para em um obstáculo.</li>
<li>Monitorar o site: <a href="https://thingspeak.com/channels/96723" target="_blank">Site de dados da estação</a> e veja se os dados ambiente continuamente sido exibidos.</li>
</ol>
<p>O vídeo mostra o protótipo completo sendo controlado pelo aplicativo Android , capturando dados do sensor e mostrando na Internet.</p>
<p><a href="https://youtu.be/QwMHXr8PvC8">https://youtu.be/QwMHXr8PvC8</a></p>
<p>Os códigos para o Arduino e para o RPi:</p>
<p class="p1"><a href="https://www.dropbox.com/sh/wfp4r1h4abspj48/AACY94rTT6whDcEXo-LSVSVva?dl=0">Codigos para o Arduino</a></p>
<p class="p1"><a href="https://www.dropbox.com/sh/rzihv0nhwzwtibo/AADgeqVhlq4Vdk3NQ6VZ15Mba?dl=0">Codigos em Python para o RPi</a></p>
<p class="p1"></p>
<p class="p1"></p>
<h5 class="p1"><span class="font-size-5">Conclusão:</span></h5>
<div class="tiled-gallery type-rectangular"><div class="gallery-row"><div class="gallery-group images-1"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/img_3178/"><img src="https://mjrobot.files.wordpress.com/2016/03/img_3178.jpg?w=442&h=589&crop=1" width="442" height="589" title="IMG_3178" alt="IMG_3178"/></a></div>
</div>
<div class="gallery-group images-2"><div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/img_3179/"><img src="https://mjrobot.files.wordpress.com/2016/03/img_3179.jpg?w=390&h=292&crop=1" width="390" height="292" title="IMG_3179" alt="IMG_3179"/></a></div>
<div class="tiled-gallery-item tiled-gallery-item-large"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/img_3171/"><img src="https://mjrobot.files.wordpress.com/2016/03/img_3171.jpg?w=390&h=293&crop=1" width="390" height="293" title="IMG_3171" alt="IMG_3171"/></a></div>
</div>
</div>
</div>
<p class="p1"></p>
<p class="p1">No futuro pretendo incluir algumas características adicionais ao projeto:</p>
<ul>
<li>Controlar o Rover pel<br/> a internet.</li>
<li class="p1">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.</li>
<li class="p1">Fonte de energia usando painéis solares.</li>
</ul>
<p class="p1">Uma idéia é usar como estrutura o EasyRoverDS do Maurício aqui do Garagem:</p>
<p class="p1"><a href="http://mauriciodgsantos.wix.com/easyroverds">http://mauriciodgsantos.wix.com/easyroverds</a></p>
<p class="p1"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979603002?profile=original" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979603002?profile=RESIZE_480x480" width="400" class="align-full"/></a></p>
<p class="p1"></p>
<p class="p1">Para mais projetos e tutoriais, por favor, visite meu Blog.</p>
<p class="p1"><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596245?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979596245?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<p class="p1"><a href="http://mjrobot.org/2016/03/22/o-mars-rover-tupiniquim-prototipo-de-uma-estacao-movel-para-captura-de-dados-ambientais/" target="_blank">Link para o projeto completo no Blog MJRoBot.org</a></p>
<p class="p1"></p>
<p class="p1"></p>
<p class="p1">Obrigado e espero que este projeto possa ajudar a outros garagistas aqui a aprender sobre o Raspberry Pi, Internet das coisas (IoT), Arduino , robôs , etc.</p>
<p class="p1">Abração </p>
<p class="p1"></p>
<p class="p1"></p>
<p class="p1"></p>Tutorial: Braço robótico programável – Projeto Finaltag:labdegaragem.com,2016-02-18:6223006:BlogPost:5128892016-02-18T15:46:43.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979594645?profile=original" target="_self"><img class="align-full" src="http://storage.ning.com/topology/rest/1.0/file/get/1979594645?profile=RESIZE_1024x1024" width="700"></img></a></p>
<p></p>
<p>Depois de um longo e tenebroso inverno, vamos ao projeto de verdade! Afinal, já era sem tempo! O circuito como comentado na introdução, vai ser baseado no Arduino MEGA, alguns potenciômetros, botões e LEDS para o “painel de controle local”. Um modulo HC-06 conectará o braço, via rede Bluetooth, com um celular Android (controle em modo remoto).</p>
<h4>BRAÇOS…</h4>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979594645?profile=original" target="_self"><img width="700" src="http://storage.ning.com/topology/rest/1.0/file/get/1979594645?profile=RESIZE_1024x1024" width="700" class="align-full"/></a></p>
<p></p>
<p>Depois de um longo e tenebroso inverno, vamos ao projeto de verdade! Afinal, já era sem tempo! O circuito como comentado na introdução, vai ser baseado no Arduino MEGA, alguns potenciômetros, botões e LEDS para o “painel de controle local”. Um modulo HC-06 conectará o braço, via rede Bluetooth, com um celular Android (controle em modo remoto).</p>
<h4>BRAÇOS ROBÓTICOS:</h4>
<p></p>
<p><img src="http://storage.ning.com/topology/rest/1.0/file/get/1979596493?profile=original" width="298" class="align-left"/></p>
<p><span>Os braços robóticos podem ser classificados segundo o número de “juntas”, ou “graus de liberdade” (DOF – Degree of Freedom) que possuem.</span> Por exemplo:</p>
<ul>
<li>Base giratória (de 360 ou 180 graus). A base é conhecida como <span class="font-size-2">“Waist”</span> ou simplesmente “Base”.</li>
<li>O ombro ou “Shoulder” é o responsável por levantar ou abaixar o braço na vertical</li>
<li>O cotovelo ou”Elbow”, fará o braço ir para a frente ou para trás.</li>
<li>A garra ou “Gripper” (em alguns casos “Claw”), funciona abrindo ou fechando para “agarrar coisas”.</li>
</ul>
<p></p>
<p>Observe que nesse diagrama só o braço propriamente dito já possui 3 DOF. A garra que no caso do meArm (4DOF) adiciona o quarto elemento. Nesse projeto ficaremos por aqui (até 4 DOF), mas é obvio que poderíamos ter mais “juntas no corpo” e principalmente a garra poderia ser mais sofisticada com 2 ou 3 DOF (rotação e elevação).</p>
<p></p>
<p>Os Braços que serão testados nesse projeto serão o SanSmart 3 DOF e o meArm 4DOF </p>
<p><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596763?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979596763?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></span></p>
<p></p>
<p></p>
<p><a width="300" href="http://storage.ning.com/topology/rest/1.0/file/get/1979598984?profile=RESIZE_320x320" target="_self"><img width="300" src="http://storage.ning.com/topology/rest/1.0/file/get/1979598984?profile=RESIZE_320x320" width="300" class="align-right"/></a></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p style="text-align: right;"><em> O braço ao lado por exemplo, possui 5DOF e foi desenvolvido pela <a href="http://mauriciodgsantos.wix.com/easyds">EASYDS</a>, que possui uma linha completa de Kits Robóticos Educacionais em MDF. Vale a pena dar uma olhada no site.</em></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<h4>O CIRCUITO:</h4>
<p>Para o acionamento das juntas serão utilizados servo motores conectados diretamente ao Arduino, mas poderiam também ser utilizados “Stepper Motors” para maior torque e precisão.</p>
<p>A escolha adequada dos servos é muito importante (existem servos baratos chineses que são muito mal construídos como por exemplo o MG995, que infelizmente são os que vieram com meu SanSmart 3DOF aArm) .</p>
<p>A alimentação dos servos deve ser separada do Arduino e demais componentes. Uma fonte externa de 5 a 6V deve funcionar sem problemas (verifique o datasheet de seus servos para verificar a faixa de voltagem apropriada). Uma prática comum também é a utilização de capacitores de 470uF entre VCC e GND para minimizar os ruídos gerados pelos motores internos dos servos. Não se esqueça de conectar todos os terras (fonte externa com o Arduino).</p>
<p>Caso os servos tenham problemas e vibrem muito, faça ajustes nos delays de seu codigo. É importante que os servos tenham tempo para chegar a um determinado ponto antes de receber um novo comando. Também vale a pena verificar se os servos são digitais ou analógicos, pois apesar de serem parecidos mecanicamente, os digitais trabalham em uma frequência de 300Hz enquanto que os analógicos com 50Hz. A biblioteca standard do Arduino <Servo.h> foi desenvolvida para servos analógicos e podem ser modificadas caso necessário, para para um melhor funcionamento com servos digitais.</p>
<p></p>
<p>Abaixo o diagrama completo:</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979601010?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979601010?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<h4>O CÓDIGO:</h4>
<p> </p>
<p>O projeto não é complicado, mas possui muitas variáveis. O mais prudente foi definir-las claramente e deixar suas declarações en um arquivo exclusivo:</p>
<pre><em><strong>ArmDefine.h</strong></em><br/><br/>
</pre>
<p>No arquivo também foram definidos os valores mínimo, máximo e iniciais para os servos. No codigo incluído nesse tutorial, existem dois conjuntos de parâmetros referentes aos braços robóticos que testei em meu projeto (claro que somente um grupo de constantes deverá ser utilizado):</p>
<ol>
<li>MeArm 4-DOF<ul>
<li><pre><span style="color: #800080;">#define minGrip 15 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define minBase 0 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define minShou 60 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define minElbw 60</span></pre>
</li>
<li><pre><span style="color: #800080;">#define maxGrip 45 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define maxBase 170 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define maxShou 180 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define maxElbw 150</span></pre>
<pre><span style="color: #800080;">#define midGrip 30 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define midBase 87 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define midShou 138 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define midElbw 100</span></pre>
</li>
</ul>
</li>
<li>SS 3-DOF<ul>
<li><pre><span style="color: #800080;">#define minGrip 75 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define minBase 5 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define minShou 5 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define minElbw 0</span></pre>
<pre><span style="color: #800080;">#define maxGrip 125 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define maxBase 150 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define maxShou 155 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define maxElbw 0</span></pre>
<pre><span style="color: #800080;">#define midGrip 100 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define midBase 90 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define midShou 90 </span></pre>
</li>
<li><pre><span style="color: #800080;">#define midElbw 0</span></pre>
</li>
</ul>
</li>
</ol>
<p></p>
<p><span><span>Para cada tipo de braço vão existir parâmetros distintos e é importante que você encontre os correctos para o seu. O que sugiro é que inicialmente os potenciômetros fiquem em seu ponto médio e que o Mapping das saídas PWM sejam definidas com os valores standard: Max = 255, Min = 0 e Mid = 126 ("#defines" acima). Ao se ir variando os potenciômetros (um a um), deve-se observar no Monitor Serial (ou LCD) quais deverão ser os valores mínimos e máximos em que o braço trabalhará corretamente. Estes serão os valores finais a serem utilizados para as definições.</span></span></p>
<p></p>
<p>Para a "gravação" dos conjuntos de coordenadas (ou steps) que o robot deverá reproduzir, utilizarei arrays de dados:</p>
<pre><span style="color: #800080;"> int gripPosition[100]; </span><br/><span style="color: #800080;"> int basePosition[100]; </span><br/>
<span style="color: #800080;"> int shouPosition[100]; </span><br/>
<span style="color: #800080;"> int elbwPosition[100];</span><br/>
<br/>
</pre>
<pre><span style="color: #800080;"> int positionIndex = 0;</span><br/><br/>
</pre>
<p>Observe que não estou guardando as posições "gravadas" e ao finalizar -se o "programa do robot", o índice voltará a zero e o robot esperará pela gravação de uma nova sequência. Se poderia guardar esses arrays de dados na EEPROM do Arduino, por exemplo. Isso faria com que o programa pudesse ser executado infinitas vezes, ou até mesmo possuir mais de um programa armazenado. Fica aqui a dica para o desenvolvimento de um projeto mais sofisticado.</p>
<h5>A lógica do programa:</h5>
<p>O bloco principal (“Loop”) é na verdade bem simples:</p>
<ol>
<li>Verifica se há mensagens no buffer serial, provenientes do Android</li>
<li>Se há mensagens, verifica se o controle deverá ser Local ou Remoto ( o default é Local).</li>
<li>Verifica se existe um comando para executar o “programa” (sequencia de passos). Se existe, o executa. Do contrário, entende que o “programa” não está completo e ainda se devem gravar novos passos.</li>
<li>Se há uma nova posição é definida, adiciona a mesma ao programa</li>
<li>Volta ao início e executa o passo 1 novamente.</li>
</ol>
<p><span style="color: #800080;">void loop()</span><br/> <span style="color: #800080;">{</span> <br/> <span style="color: #800080;"> checkBTcmd();</span><br/> <span style="color: #800080;"> defineLocalRemote();</span><br/> <br/> <span style="color: #800080;"> execTaskCmd = digitalRead (execTaskPin);</span><br/> <span style="color: #800080;"> if(execTaskCmd == HIGH || command == "runon")</span><br/> <span style="color: #800080;"> {</span><br/> <span style="color: #800080;"> runProgram();</span><br/> <span style="color: #800080;"> }</span><br/> <span style="color: #800080;"> else recArmPosition();</span> <br/> <span style="color: #800080;"> command = "";</span><br/> <span style="color: #800080;">}</span></p>
<p></p>
<p>A função <span style="color: #800080;"><strong>checkBTcmd()</strong></span> monta uma string a partir dos caracteres que chegam do modulo BT. Essa string é passada a variável “command”.</p>
<p><span>A função </span><span style="color: #800080;"><strong>defineLocalRemote()</strong></span><span><span style="color: #800080;"><strong> </strong></span>analisará a variável “command” verificando se </span><span>um </span><span>comando para mudar a função de local a remoto ou vice e versa é recebida. O comando de Alarm também é analisado aqui.</span><span> </span><span>Pela </span><span>lógica do programa, se</span><span> “Alarm” </span><span>for</span><span> acionado no no Android, </span><span>significará que o braço deverá </span><span> passar obrigatoriamente ao modo Remoto.</span></p>
<p>A função <strong><span style="color: #800080;">runProgram ()</span></strong> executará as preparações, como acender/apagar os LEDS correspondentes, etc. e principalmente invocará a função: <strong><span style="color: #800080;">executeTask()</span></strong>. Essa última, é a função que contem a lógica de execução da sequencia de steps. A função incrementa o “positionIndex” enviando ao braço uma a uma, as coordenadas para seu posicionamento usando a função:<span style="color: #800080;"><strong> armPosition(grip, base, shoulder, elbow).</strong></span></p>
<p>Por último, a função que realmente comandará os servos e gravará os “steps” é a <strong><span style="color: #800080;">recArmPosition()</span></strong>. Dependendo do comando recebido do Android, esta função deverá definir se o posicionamento dos servos será comandado através dos potenciômetros, ou através dos “sliders” do Android. A cada mudança de posição, esta função enviará as coordenadas aos servos via a função <span style="color: #800080;"><strong>armPosition(grip, base, shoulder, elbow)</strong></span>. A leitura da posição dos potenciômetros ou dos sliders e o correspondente acionamento dos servos ocorrerá até o momento em que o comando de “Gravar” ou “PROGRAM” seja acionado. Nesse momento o índice de posição dos Arrays será incrementado e as coordenadas guardadas.</p>
<p>Para simplificação de entendimento, todo o codigo foi baseado em funções específicas. O bloco de Setup, Loop e as funções descritas anteriormente estão praticamente todas no file:</p>
<pre><em><strong>MJRoBot_Arm_Robot_Task_Prgm.ino</strong></em><br/><br/>
</pre>
<p>As funções mais gerais como leituras de comandos BT: <span style="color: #800080;"><strong>void checkBTcmd()</strong></span>; gerador de som: <span style="color: #800080;"><strong>void beep(int pin, int freq, long ms)</strong></span> e debouncing : <strong><span style="color: #800080;">boolean debounce(int pin)</span></strong>; estão no file:</p>
<pre><em><strong>General_Functions.ino</strong></em></pre>
<p></p>
<p>Um dado importante. Como o Arduino executará instruções baseadas em um clock de 16Mhz, é de se esperar que os botões de comando sejam lidos centenas ou até milhares de vezes por segundo, daí ser importantíssimo fazer um “debouncing” do botão que define a gravação do step.</p>
<p></p>
<p>O quarto e último file que compõe o código é:</p>
<pre><em><strong>Arm_Ctrl_and_Display.ino</strong></em></pre>
<p></p>
<p>Nesse file estão principalmente as funções de leitura de potenciômetros: <strong><span style="color: #800080;">bool readPotenciometers()</span></strong>; leitura dos sliders do Android: <strong><span style="color: #800080;">bool readSliders()</span></strong>; posicionamento dos servos: <strong><span style="color: #800080;">void armPosition(int gripp, int basee, int shoulder, int elbow).</span></strong> As demais funções do file são auxiliares para display de dados no LCD, Serial Monitor, alarmes, etc.</p>
<p>O código completo para o projeto pode ser baixado aqui:</p>
<p><a href="https://www.dropbox.com/sh/jaasppunwbcvo1p/AADnNayGYZ4pGIu_ufnLftO8a?dl=0" target="_blank">Link para o código do Arduino</a></p>
<p></p>
<p>Abaixo um vídeo do braço robótico 4DOF “meArm”:</p>
<p><a href="https://youtu.be/WgNhvga111A" target="_blank">Video: MeArm controlled by Android</a></p>
<p></p>
<p>No vídeo o braço está sendo programado remotamente através da nova versão da app Android</p>
<pre><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979603144?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979603144?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></pre>
<p>A app pode ser baixada gratuitamente aqui:</p>
<p><a href="https://play.google.com/store/apps/details?id=appinventor.ai_mjrovai.MJRoBot_BT_ARM_CTRL_V2_1&hl=en" target="_blank">MJRoBot Arduino Arm Robot Ctrl</a>.</p>
<p></p>
<p>Agora é só colocar a mão na massa, quer dizer no Arduino e mandar bala! Até a próxima!</p>
<p></p>
<p>Para mais exemplos, códigos, etc. Por favor, visite meu blog:</p>
<p><a href="http://mjrobot.org" target="_blank">MJRoBot.org</a></p>
<pre><br/><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979603889?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979603889?profile=RESIZE_1024x1024" width="750" class="align-full"/></a><br/>
<br/>
</pre>
<p></p>Tutorial: Braço robótico programável – Introduçãotag:labdegaragem.com,2016-02-06:6223006:BlogPost:5106992016-02-06T17:00:00.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p>O objetivo desse tutorial é o desenvolvimento em etapas de um projeto para o controle e programação de um braço robótico, simulando as funções básicas de um robô industrial.</p>
<h4><span>ESPECIFICAÇÕES</span>:</h4>
<ul>
<li>O robô deverá ter duas funções básicas:<ul>
<li><span>Programa</span>: gravar posições do braço em 3 <span class="s1">dimensões</span></li>
<li><span>Run</span>: executar o programa de trabalho (ou seja, executar em sequencia as posições gravadas na etapa de…</li>
</ul>
</li>
</ul>
<p>O objetivo desse tutorial é o desenvolvimento em etapas de um projeto para o controle e programação de um braço robótico, simulando as funções básicas de um robô industrial.</p>
<h4><span>ESPECIFICAÇÕES</span>:</h4>
<ul>
<li>O robô deverá ter duas funções básicas:<ul>
<li><span>Programa</span>: gravar posições do braço em 3 <span class="s1">dimensões</span></li>
<li><span>Run</span>: executar o programa de trabalho (ou seja, executar em sequencia as posições gravadas na etapa de programa.</li>
</ul>
</li>
<li>O robô executará o programa até que o comando de “abortar” seja utilizado.</li>
<li>O projeto deverá controlar robots de 3 ou 4 DOF (“Degrees of Freedom”).</li>
<li>O robô deverá ser controlado em modo “local” e “remoto” (via celular)</li>
<li>Durante o programa se poderá mudar o controle de “local” a “remoto” e vice-e-versa.</li>
<li>Deverá possuir sinalização tanto visual (LEDS e display) quanto sonora</li>
<li>Deverá possuir função de alarme acionado remotamente.</li>
</ul>
<h4>O PROJETO:</h4>
<p>O diagrama abaixo mostra o “Bill of Material” que será utilizado no projeto:</p>
<p></p>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979593523?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979593523?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<p></p>
<p><span>Para o projeto, optarei pelo Arduino MEGA para não ter que me preocupar com o número de portas I/Os. O UNO funcionaria sem problemas, mas se deveria utilizar algum método de expansão de portas. Existem várias opções que podem ser facilmente encontradas na internet, como um decodificador 74138 por exemplo (veja o site: </span><a href="http://www.embarcados.com.br/arduino-expandindo-ios-parte-1/" target="_blank">“Expandindo os I/Os do Arduino”</a><span>).</span></p>
<p></p>
<p><span>Para a rede Bluetooth utilizarei o HC-06 (o qual explico em detalhes no tutorial </span><a href="http://mjrobot.org/2016/01/30/conectando-coisas-atraves-do-bluetooth/">“Conectando “coisas” através do Bluetooth”</a><span>).</span></p>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979595469?profile=original" target="_self"><img width="100" src="http://storage.ning.com/topology/rest/1.0/file/get/1979595469?profile=RESIZE_180x180" width="75" class="align-left" height="120"/></a>A app Android utilizado para o “modo remoto”, foi desenvolvida utilizando-se a ferramenta <a href="http://appinventor.mit.edu/explore/" target="_blank">MIT appinventor2</a>, uma plataforma tão poderosa quanto simples para esse tipo de app baseado no Android. No futuro pretendo explorar a criação de apps desse tipo aqui no Blog. Por enquanto, o app está disponível para ser baixado gratuitamente na loja da Google: <a href="https://play.google.com/store/apps/details?id=appinventor.ai_mjrovai.MJRoBot_BT_ARM_CTRL_V2_1" target="_blank">MJRoBot Arduino Arm Robot Control</a>.</p>
<p></p>
<p></p>
<p>Para se ter uma ideia geral do projeto, os vídeos abaixo mostram como deverá ficar o projeto final:</p>
<p></p>
<p>Primeiro protótipo sendo programado em “modo local”:</p>
<p><span><a href="https://youtu.be/ceLIAkFdSEM">https://youtu.be/ceLIAkFdSEM</a></span></p>
<p></p>
<p><span><span>No seguinte vídeo, o robô é programado de maneira remota via rede Bluetooth:</span></span></p>
<p><span><a href="https://youtu.be/OHl-oCbYtx0">https://youtu.be/OHl-oCbYtx0</a></span></p>
<p><span> </span></p>
<p><span><span>Nos próximos posts, detalharei os passos necessários para o desenvolvimento do projeto.</span></span></p>
<p><span><span>Até lá!</span></span></p>
<p></p>
<p>Para mais tutoriais, demos, vídeos, etc. visite meu blog:</p>
<p><a rel="nofollow" href="http://mjrobot.org/" target="_blank">MJRoBot.org</a></p>
<p>Um abraço e até mais!</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1802503322?profile=original" target="_self"></a></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979595514?profile=original" target="_self"><img width="750" src="http://storage.ning.com/topology/rest/1.0/file/get/1979595514?profile=RESIZE_1024x1024" width="750" class="align-full"/></a></p>
<p></p>O ESP8266 como WebServer (usando o Mega)tag:labdegaragem.com,2016-01-17:6223006:BlogPost:5069212016-01-17T17:23:11.000ZMarcelo Rovaihttps://labdegaragem.com/profile/MarceloRovai
<p>Depois de testar o modulo com vários comandos AT (vale a pena dar uma sapeada no arquivo anexo, bem legal!), parti para fazer o modulo funcionar como Web Server. Partído que tinha aprendido, principalmante com um tutorial do blog FILIPEFLOP:</p>
<p><a href="http://blog.filipeflop.com/wireless/esp8266-arduino-tutorial.html">http://blog.filipeflop.com/wireless/esp8266-arduino-tutorial.html</a></p>
<p><strong><span class="font-size-5">O Circuito:…</span></strong></p>
<p></p>
<p>Depois de testar o modulo com vários comandos AT (vale a pena dar uma sapeada no arquivo anexo, bem legal!), parti para fazer o modulo funcionar como Web Server. Partído que tinha aprendido, principalmante com um tutorial do blog FILIPEFLOP:</p>
<p><a href="http://blog.filipeflop.com/wireless/esp8266-arduino-tutorial.html">http://blog.filipeflop.com/wireless/esp8266-arduino-tutorial.html</a></p>
<p><strong><span class="font-size-5">O Circuito:</span></strong></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979592254?profile=original" target="_self"><img width="350" src="http://storage.ning.com/topology/rest/1.0/file/get/1979592254?profile=RESIZE_480x480" width="350" class="align-full"/></a></p>
<p></p>
<p><span class="font-size-5"><strong>O código:</strong></span></p>
<p class="p1"></p>
<p class="p2">/*************************************************************************</p>
<p class="p2">* Web Server with ESP8266</p>
<p class="p2">* Based on: FILIPEFLOP <a href="http://blog.filipeflop.com/wireless/esp8266-arduino-tutorial.html">http://blog.filipeflop.com/wireless/esp8266-arduino-tutorial.html</a></p>
<p class="p2">* Adapted by Marcelo Jose Rovai</p>
<p class="p2">**************************************************************************/</p>
<p class="p3"></p>
<p class="p2">#define esp8266 Serial2</p>
<p class="p2">#define CH_PD 4 </p>
<p class="p2">#define speed8266 115200 // This is the speed that worked with my ESP8266</p>
<p class="p3"> </p>
<p class="p2">#define DEBUG true</p>
<p class="p3"> </p>
<p class="p2">void setup()</p>
<p class="p2">{</p>
<p class="p2"> esp8266.begin (speed8266); </p>
<p class="p2"> Serial.begin(9600);</p>
<p class="p2"> reset8266(); // Pin CH_PD needs a reset before start communication</p>
<p class="p3"> </p>
<p class="p2"> sendData("AT+RST\r\n", 2000, DEBUG); // reset</p>
<p class="p2"> sendData("AT+CWJAP=\"ROVAI TIMECAP\",\"mjr747@1\"\r\n", 2000, DEBUG); //Connect network</p>
<p class="p2"> delay(3000);</p>
<p class="p2"> sendData("AT+CWMODE=1\r\n", 1000, DEBUG);</p>
<p class="p2"> sendData("AT+CIFSR\r\n", 1000, DEBUG); // Show IP Adress</p>
<p class="p2"> sendData("AT+CIPMUX=1\r\n", 1000, DEBUG); // Multiple conexions</p>
<p class="p2"> sendData("AT+CIPSERVER=1,80\r\n", 1000, DEBUG); // start comm port 80</p>
<p class="p2">}</p>
<p class="p3"> </p>
<p class="p2">void loop()</p>
<p class="p2">{</p>
<p class="p2"> if (esp8266.available()) // check if 8266 is sending data</p>
<p class="p2"> {</p>
<p class="p2"> if (esp8266.find("+IPD,"))</p>
<p class="p2"> {</p>
<p class="p2"> delay(300);</p>
<p class="p2"> int connectionId = esp8266.read() - 48;</p>
<p class="p3"> </p>
<p class="p2"> String webpage = "<head><meta http-equiv=""refresh"" content=""3"">";</p>
<p class="p2"> webpage += "</head><h1><u>MJRoBot ==> WebServer (ESP8266) </u></h1><h2>Arduino Pin: ";</p>
<p class="p2"> webpage += "D8 status ==> ";</p>
<p class="p2"> int a = digitalRead(8);</p>
<p class="p2"> webpage += a;</p>
<p class="p2"> webpage += "<h2>Arduino Pin: D9 status ==> ";</p>
<p class="p2"> int b = digitalRead(9);</p>
<p class="p2"> webpage += b;</p>
<p class="p2"> webpage += "<h2>Arduino Pin: A0 data ===> ";</p>
<p class="p2"> int c = analogRead(0);</p>
<p class="p2"> webpage += c;</p>
<p class="p2"> webpage += "</h2>";</p>
<p class="p2"> String cipSend = "AT+CIPSEND=";</p>
<p class="p2"> cipSend += connectionId;</p>
<p class="p2"> cipSend += ",";</p>
<p class="p2"> cipSend += webpage.length();</p>
<p class="p2"> cipSend += "\r\n";</p>
<p class="p3"> </p>
<p class="p2"> sendData(cipSend, 1000, DEBUG);</p>
<p class="p2"> sendData(webpage, 1000, DEBUG);</p>
<p class="p3"> </p>
<p class="p2"> String closeCommand = "AT+CIPCLOSE=";</p>
<p class="p2"> closeCommand += connectionId; // append connection id</p>
<p class="p2"> closeCommand += "\r\n";</p>
<p class="p3"> </p>
<p class="p2"> sendData(closeCommand, 3000, DEBUG);</p>
<p class="p2"> }</p>
<p class="p2"> }</p>
<p class="p2">}</p>
<p class="p3"> </p>
<p class="p2">/*************************************************/ </p>
<p class="p2"> // Send AT commands to module</p>
<p class="p2">String sendData(String command, const int timeout, boolean debug)</p>
<p class="p2">{</p>
<p class="p2"> String response = "";</p>
<p class="p2"> esp8266.print(command);</p>
<p class="p2"> long int time = millis();</p>
<p class="p2"> while ( (time + timeout) > millis())</p>
<p class="p2"> {</p>
<p class="p2"> while (esp8266.available())</p>
<p class="p2"> {</p>
<p class="p2"> // The esp has data so display its output to the serial window</p>
<p class="p2"> char c = esp8266.read(); // read the next character.</p>
<p class="p2"> response += c;</p>
<p class="p2"> }</p>
<p class="p2"> }</p>
<p class="p2"> if (debug)</p>
<p class="p2"> {</p>
<p class="p2"> Serial.print(response);</p>
<p class="p2"> }</p>
<p class="p2"> return response;</p>
<p class="p2">}</p>
<p class="p3"></p>
<p class="p2">/*************************************************/</p>
<p class="p2">// Reset funtion to accept communication</p>
<p class="p2">void reset8266 ()</p>
<p class="p2">{</p>
<p class="p2"> pinMode(CH_PD, OUTPUT);</p>
<p class="p2"> digitalWrite(CH_PD, LOW);</p>
<p class="p2"> delay(300);</p>
<p class="p2"> digitalWrite(CH_PD, HIGH);</p>
<p class="p2">}</p>
<p></p>
<p></p>
<p><strong><span class="font-size-5">A web Page:</span></strong></p>
<p><span class="font-size-3">Note que o endereço da pagina é o segundo IP que aparece no Serial monitor com o comando AT+CIFSR na fase de Set-up (veja a copia do Serial monitor abaixo): </span></p>
<p>+CIFSR:STAIP,"10.0.1.2"</p>
<p><span class="font-size-3"> </span></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979594240?profile=original" target="_self"><img width="400" src="http://storage.ning.com/topology/rest/1.0/file/get/1979594240?profile=RESIZE_480x480" width="400" class="align-full"/></a></p>
<p></p>
<p><strong><span class="font-size-5">A saída no Serial Monitor:</span></strong></p>
<p>1. A conexão com o modulo esp8266</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979594347?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/1979594347?profile=original" width="461" class="align-full"/></a></p>
<p></p>
<p></p>
<p>2. A comunicação:</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596477?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/1979596477?profile=original" width="483" class="align-full"/></a></p>
<p></p>
<p>Eu fiz um pequeno vídeo para dar uma visão do WebServer funcionando:</p>
<p><a href="https://youtu.be/VvL0lzYnj-8" target="_blank">ESP8266 como webserver</a></p>
<p></p>
<p>Documento legal com dicas de comandos AT para configurar o esp8266:</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/1979596569?profile=original" target="_self">ESP8266_WiFi_Module_Quick_Start_Guide_v_1.0.4.pdf</a></p>
<p></p>
<p>meu Blog:</p>
<p><a href="http://mjrobot.wordpress.com" target="_blank">MJRoBot Web/Blob</a></p>
<p></p>