A Internet das Coisas (ou Internet of Things - IoT) busca conectar vários dispositivos para facilitar o seu dia a dia - de geladeira a relógios inteligentes - por meio da internet. Para brincar um pouco com esses projetos IoT, a placa Arduino é um dos dispositivos mais utilizados. Neste tutorial, iremos desenvolver um aplicativo Android que consegue acender um led em uma placa arduino, através do protocolo http. Todos os dispositivos estarão na mesma rede para simplificar o projeto. A ideia base é que o seu smartphone fará uma requisição HTTP para o Arduino e um servidor web pequeno embarcado no arduino irá responder ao comando recebido. O App enviará as mensagens em JSON.

Requisitos:

  • Uma placa Arduino UNO
  • Um dispositivo Android
  • Uma placa Ethernet para Arduino

arduino

Para iniciar, conecte a placa arduino com a placa ethernet para possibilitar o acesso à rede através do dispositivo. Iremos controlar o pino digital padrão do arduino 13, que já possui um led que liga automaticamente quando o dispositivo é ativado. Em seguida, conecte a sua placa e faça o upload do seguinte código:

        #include <SPI.h>
        #include <Ethernet.h>
        byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
        IPAddress ip(192, 168, 1, 177); // Arduino IP
        EthernetServer server(3003); // Web server Port

        #define PIN_LED 13
        
        void setup() {
            // put your setup code here, to run once:
            Serial.begin(9600);
            pinMode(PIN_LED, OUTPUT); // Set Pin 13 to OUTPUT Mode
            Serial.print("Starting...");
            Ethernet.begin(mac, ip);
            server.begin();
        }
        
        void loop() {
            // Is there a client (Our Android smartphone)
            EthernetClient client = server.available();
            if (client) {
                Serial.println("Client connected");
                //an http request ends with a blank line
                boolean currentLineIsBlank = true;
        
                while (client.connected()) {
                    while(client.available()) {
                        char c = client.read();
                        // if we've gotten to the end of the line (received a newline
                        // character) and the line is blank, the http request has ended,
                        // so we can send a reply
                        if (c == '\n' && currentLineIsBlank) {
                            int c = client.read(); 
                            if(c == '1') {
                                Serial.println("Turn On LED");
                                digitalWrite(PIN_LED, HIGH);
                            }else {
                                Serial.println("Turn Down LED");
                            }
                            Serial.println();
                            //Serial.println("Sending response");
                            // send a standard http response header
                            client.println("HTTP/1.0 200 OK");
                            client.println("Content-Type: text/html");
                            client.println("Connection: keep-alive");
                            client.println();
                            client.stop();
                        } else if (c == '\n') {
                            // you're starting a new line
                            currentLineIsBlank = true;
                        } else if (c != '\r') {
                            // you've gotten a character on the current line
                            currentLineIsBlank = false;
                        }
                    }
                }
                Serial.println();
          }
          // Stay a half of second 
          delay(300);
      }

As primeiras linhas são de configuração dos endereços MAC, IP e porta, onde o nosso servidor estará disponível. Lembre de trocar as configurações para que satisfaçam as suas configurações de rede.

Na função setup, dizemos que o nosso pino de saída que irá receber os comandos será o pino 13 e iniciamos uma conexão Ethernet com o endereço MAC e IP passados previamente.

Na função Loop lidamos com todas as conexões feitas por clientes e, caso alguma possua a mensagem ‘1’, significa que queremos dar um “blink” ou seja piscar com o pino 13.

Cliente Android: Envio de requisição HTTP

O nosso aplicativo irá enviar requisições HTTP enviando um JSON. Na nossa interface, precisaremos apenas de um botão que será responsável por enviar a requisição para acender o pino 13 no Arduino. Na minha versão, foi utilizada a biblioteca OkHttp e o projeto foi desenvolvido em Kotlin.
O código de layout não vai ser coberto neste tutorial, mas o projeto completo está disponível em meu repositório no github.
Prosseguindo, crie uma classe chamada WebClient em seu projeto e cole o seguinte código:

            import android.util.Log
            import com.squareup.okhttp.*
            import java.io.IOException
            import com.squareup.okhttp.RequestBody
           
            /**
            *
            * Created by jose on 28/10/17.
            */
            class WebClient {
               @Throws(IOException::class)
               fun doPostRequest(cmd:String): String? {
                    var answer:String? = ""
                    val client = OkHttpClient()
                    val url = "http://192.168.1.177:3003"
                    Log.d("COMMAND", "Making request: "+cmd)
                    val mediaType: MediaType = MediaType.parse("application/json; charset=utf-8")
                    val body = RequestBody.create(mediaType, cmd)
                    val request = Request.Builder()
                    .url(url)
                    .post(body)
                    .build()

                    client.newCall(request)
                        .enqueue(object: Callback {
                           override fun onFailure(request: Request?, e: IOException?) {}

                           override fun onResponse(response: Response?) {
                              val res = response?.body()?.string()
                              answer = res
                              Log.d("ANSWER:", "resp["+answer+"]")
                           }   
                     });
                     
                   return answer
                 }
            }

Este código será o responsável por criar uma thread e enviar o nosso JSON através do protocolo HTTP.
Em sua activity principal cole o seguinte código:

            import android.support.v7.app.AppCompatActivity
            import android.os.Bundle
            import android.widget.Button
            import com.example.jose.led.R
            import com.example.jose.led.util.WebClient
            import com.squareup.okhttp.OkHttpClient


            class MainActivity : AppCompatActivity() {
               lateinit var btnTurnOn: Button
               lateinit var httpClient: OkHttpClient
               
               override fun onCreate(savedInstanceState: Bundle?) {
                   super.onCreate(savedInstanceState)
                   setContentView(R.layout.activity_main)
                   initElements()

                   btnTurnOn.setOnClickListener {
                       val webClient = WebClient()
                       webClient.doPostRequest("1")
                   }
               }

               fun initElements() {
                   btnTurnOn = findViewById(R.id.btnTurnOn)
                   httpClient = OkHttpClient()
               }
            }

Este código trata apenas da interface, iniciando os elementos da UI e enviando a informação para o nosso webClient.

Conclusão

Através desse quickstart busquei passar um conhecimento básico de como criar servidores web em placas arduino e conectá-los a aplicativos android. Agora que já tem o conhecimento básico poderá facilmente estender esta aplicação para outras mais elaboradas, como ligar lâmpadas, ar-condicionado, entre outros projetos de automação residencial.

Link para os projetos:

Servidor Web Arduino: https://github.com/juzejunior/ArduinoWebServer
Cliente Android: https://github.com/juzejunior/AndroidClient