Android Studio 连接 Arduino YUN:WiFi传输传感器数据技术咨询
Hey there! Let's work through connecting your Arduino Yun to Android Studio for your smart city farm project—sounds like a really neat setup with those temperature, humidity, and water level sensors. Here's a step-by-step breakdown of how to pull sensor data into your Android app:
First off, the Arduino Yun has built-in WiFi, so you don't need an extra WiFi shield. We'll set it up as a simple server to serve sensor data when your Android app requests it.
Step 1: Configure the Yun's WiFi
Connect your Yun to your local WiFi network via the web panel (default IP: 192.168.240.1), and set a static IP address so you don't have to hunt for it later.
Step 2: Arduino Code to Serve Sensor Data
We'll use the Yun's Bridge library to create an HTTP server that returns sensor data in JSON format (easy to parse in Android):
#include <Bridge.h> #include <YunServer.h> #include <YunClient.h> YunServer server(80); // Define your sensor pins const int tempSensorPin = A0; const int humiditySensorPin = A1; const int waterLevelSensorPin = D2; void setup() { pinMode(waterLevelSensorPin, INPUT); Bridge.begin(); server.begin(); } void loop() { YunClient client = server.accept(); if (client) { // Read incoming request String request = client.readStringUntil('\r'); // Send HTTP response headers client.println("HTTP/1.1 200 OK"); client.println("Content-Type: application/json"); client.println("Connection: close"); client.println(); // Read sensor values int tempRaw = analogRead(tempSensorPin); int humidityRaw = analogRead(humiditySensorPin); int waterLevelState = digitalRead(waterLevelSensorPin); // Send data as JSON client.print("{\"temp_raw\":"); client.print(tempRaw); client.print(",\"humidity_raw\":"); client.print(humidityRaw); client.print(",\"water_level\":"); client.print(waterLevelState); client.println("}"); client.stop(); } }
Note: If your sensors need calibration (like converting analog temp values to actual °C), add that logic before sending the data.
We'll cover two common methods to fetch data: HTTP GET (great for periodic updates) and Socket communication (ideal for real-time streaming).
Option 1: HTTP GET with OkHttp (Recommended for Periodic Updates)
OkHttp is a robust, easy-to-use HTTP client for Android.
Step 1: Add Dependencies & Permissions
Add this to your module-level build.gradle file:
dependencies { implementation 'com.squareup.okhttp3:okhttp:4.12.0' }
Add internet permission to your AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" /> <!-- For Android 9+, allow cleartext HTTP (since Yun uses plain HTTP by default) --> <application ... android:usesCleartextTraffic="true"> ... </application>
Step 2: Fetch Data in Android
Use coroutines (Kotlin) or AsyncTask (Java) to run network operations off the main thread:
Kotlin Example with Coroutines
import okhttp3.OkHttpClient import okhttp3.Request import org.json.JSONObject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext // Replace with your Yun's static IP private const val YUN_STATIC_IP = "192.168.1.105" fun fetchSensorData() { GlobalScope.launch(Dispatchers.IO) { val client = OkHttpClient() val request = Request.Builder() .url("http://$YUN_STATIC_IP/") .build() client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw IOException("Request failed: ${response.code}") response.body?.string()?.let { jsonResponse -> val sensorData = JSONObject(jsonResponse) val tempRaw = sensorData.getInt("temp_raw") val humidityRaw = sensorData.getInt("humidity_raw") val waterLevel = sensorData.getInt("water_level") // Update UI on the main thread withContext(Dispatchers.Main) { // Example: textViewTemp.text = "Temp (Raw): $tempRaw" } } } } }
Java Example with AsyncTask
import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import org.json.JSONObject; import android.os.AsyncTask; import android.widget.TextView; public class SensorDataFetcher extends AsyncTask<Void, Void, JSONObject> { private static final String YUN_IP = "192.168.1.105"; private TextView tempDisplay; public SensorDataFetcher(TextView tempDisplay) { this.tempDisplay = tempDisplay; } @Override protected JSONObject doInBackground(Void... voids) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://" + YUN_IP + "/") .build(); try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) return null; return new JSONObject(response.body().string()); } catch (Exception e) { e.printStackTrace(); return null; } } @Override protected void onPostExecute(JSONObject data) { super.onPostExecute(data); if (data != null) { try { int tempRaw = data.getInt("temp_raw"); tempDisplay.setText("Temperature (Raw): " + tempRaw); } catch (Exception e) { e.printStackTrace(); } } } } // Usage: new SensorDataFetcher(tempTextView).execute();
Option 2: Socket Communication (Real-Time Updates)
If you need instant sensor updates (e.g., when water level drops), use a socket connection.
Arduino Socket Server Code
#include <Bridge.h> #include <YunServer.h> #include <YunClient.h> YunServer server(1234); YunClient client; const int tempPin = A0; const int humidityPin = A1; const int waterLevelPin = D2; void setup() { pinMode(waterLevelPin, INPUT); Bridge.begin(); server.begin(); } void loop() { if (!client.connected()) { client = server.accept(); } else { // Send sensor data every 1 second int temp = analogRead(tempPin); int humidity = analogRead(humidityPin); int waterLevel = digitalRead(waterLevelPin); String data = String(temp) + "," + String(humidity) + "," + String(waterLevel) + "\n"; client.print(data); delay(1000); } }
Android Socket Client Code (Kotlin)
import java.io.BufferedReader import java.io.InputStreamReader import java.net.Socket import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext private const val YUN_IP = "192.168.1.105" private const val YUN_PORT = 1234 fun connectToYunSocket() { GlobalScope.launch(Dispatchers.IO) { try { val socket = Socket(YUN_IP, YUN_PORT) val reader = BufferedReader(InputStreamReader(socket.inputStream)) var line: String? while (reader.readLine().also { line = it } != null) { line?.split(",")?.let { values -> if (values.size == 3) { val temp = values[0].toInt() val humidity = values[1].toInt() val waterLevel = values[2].toInt() withContext(Dispatchers.Main) { // Update UI with real-time data } } } } } catch (e: Exception) { e.printStackTrace() } } }
Key Notes
- Ensure your Android device and Arduino Yun are on the same WiFi network
- Calibrate your sensor raw values to actual units (e.g., °C, % humidity) using your sensor's datasheet formulas
- For production, consider adding error handling (e.g., retry logic if the Yun is unreachable)
内容的提问来源于stack exchange,提问作者user3797544

