Статьи

Интернет вещей с Android и Arduino: пульт дистанционного управления LED

В этом посте описывается, как  управлять удаленным светодиодом с помощью Arduino и Android . В настоящее время новой появляющейся технологией является  Интернет вещей  ( IoT ): иными словами, все физические объекты (вещи) связаны друг с другом с помощью интернет-инфраструктуры. Ардуино  является одним из наиболее важных объектов в этой экосистеме. В этом посте мы рассмотрим, как интегрировать  Android с Arduino, сделав первый шаг в IoT. Даже Google на  io15  представил свою новую инфраструктуру IoT под названием  Brillo .
Как уже говорилось, мы хотим управлять удаленным светодиодом, подключенным к Arduino Uno, используя смартфон Android.

Обзор IoT

На рисунке ниже показаны основные объекты, вовлеченные в  проект IoT :

Что нам нужно это:

  • Arduino Uno
  • Ethernet-щит
  • Смартфон с Android

Все объекты находятся в одной сети для простоты.
Идея заключается в том, что смартфон отправляет HTTP-запрос в 
Arduino . На Arduino работает очень маленький и простой 
веб-сервер,  принимающий HTTP-запрос. Для простоты приложение отправляет запрос JSON, который содержит светодиодный статус.

Arduino: веб-сервер и соединения


Со стороны Arduino нам просто нужно подключить светодиод к основной плате Arduino и управлять им с помощью одного из выходов Arduino.
Самая сложная часть — это создание веб-сервера, который обрабатывает HTTP-запрос. Изображение ниже показывает, как Arduino подключен к светодиоду:


Как видите, соединение очень простое.  
Arduino эскиз  показан ниже:

#include <spi.h>
#include <ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 130); // Arduino IP Add
EthernetServer server(80); // Web server

// Http data
String reqData; // Request from Smartphone
String header;
int contentSize = -1;
String CONTENT_LENGTH_TXT = "Content-Length: ";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(3, OUTPUT); // Set Pin 3 to OUTPUT Mode
  Serial.print("Ready...");
  //
  Ethernet.begin(mac, ip); 
  server.begin(); 
}

void loop() {
  EthernetClient client = server.available(); // Is there a client (Our Android smartphone)

  if (client) {
    // Let's start reading
    boolean isLastLine = true;
    boolean isBody = false;
    header = "";
    reqData = "";
    int contentLen = 0;

    Serial.print("Client connected!");
    while (client.connected()) {
            if (client.available()) {
              // Read data
              char c = client.read();

              // Serial.print(c);

              if (contentSize == contentLen) {
               // Serial.println("Body ["+reqData+"]");

                int idx = reqData.indexOf(":");
                String status = reqData.substring(idx + 1, idx + 2);
                Serial.println("Status : " + status);
                if (status.equals("1")) {
                  digitalWrite(3, HIGH);
                }
                else {
                  digitalWrite(3, LOW);
                }

                client.println("HTTP/1.1 200 OK");
                client.println("Content-Type: text/html");
                client.println("Connection: close");
                client.println();
                // send web page
                client.println("");
                client.println("");
                delay(1);
                break;
              }


              if (c == '\n' && isLastLine) {
                  isBody = true;
                  int pos = header.indexOf(CONTENT_LENGTH_TXT);
                  String tmp = header.substring(pos, header.length());
                  //Serial.println("Tmp ["+tmp+"]");
                  int pos1 = tmp.indexOf("\r\n");
                  String size = tmp.substring(CONTENT_LENGTH_TXT.length(), pos1);
                  Serial.println("Size ["+size+"]");
                  contentSize = size.toInt();

              }

              if (isBody) {
                reqData += c;
                contentLen++;
              }
              else {
               header += c;
              }


              if (c == '\n' ) {
               isLastLine = true;
              }
              else if (c != '\r' ) {
                isLastLine = false;
              }



            }
    }

    // Close connection
    Serial.println("Stop..");
    client.stop();
  }
}

Почти весь  исходный код arduino  используется для обработки HTTP-соединения. Обратите внимание, что в строке 3 мы устанавливаем  MAC-адрес  сетевого экрана, а в строке 4 — IP-адрес.

Android-клиент: отправка HTTP-запроса

Со стороны Android все намного проще; пользовательский интерфейс Android показан ниже:

Есть одна простая кнопка, когда пользователь нажимает на нее,  приложение отправляет HTTP-запрос в Arduino .
Макет приложения очень прост и здесь не рассматривается, ядро ​​приложения — это то, где обрабатывается нажатие кнопки:

ledView = (ImageView) findViewById(R.id.ledImg);
// Set default image
ledView.setImageResource(R.drawable.white_circle);

// Init HTTP client
client = new HttpClient();

ledView.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
     client.doRrequest(status ? "1" : "0");
     status = !status;
     if (status)
         ledView.setImageResource(R.drawable.white_circle);
     else
         ledView.setImageResource(R.drawable.red_circle);

  }
});

Когда пользователь касается кнопки, приложение отправляет HTTP-запрос с использованием  HTTP-клиента . В этом случае этот проект использует  OkHttp . HTTP-клиент очень прост:

public void doRrequest(String status) {
  initClient();
  Log.d("AA", "Making request..["+status+"]");
  Request req = new Request.Builder()
                .url(URL)
                .post(RequestBody.create(JSON, createJSON(status)))
                .build();

  client.newCall(req).enqueue(new Callback() {
         @Override
         public void onFailure(Request request, IOException e) {              }

         @Override
         public void onResponse(Response response) throws IOException {
            Log.d("AA", "resp [" + response.body().string() + "]");
         }
  });

}

Ниже приведены некоторые изображения моей работы: