В этом посте описывается, как управлять удаленным светодиодом с помощью 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() + "]");
}
});
}
Ниже приведены некоторые изображения моей работы: