Φτιάχνοντας ένα Έξυπνο Σπίτι, και έλεγχος από το Android (μέρος 5ο)
- Παρασκευή, 10 Μαΐου 2013 16:13
Φτάνοντας στο 5ο μέρος της κατασκευής του "Έξυπνου Σπιτιού", θα κατασκευάσουμε την Android εφαρμογή που θα λαμβάνει δεδομένα από αισθητήρες. (1o, 2o, 3o, 4o)
Μέχρι τώρα έχουμε προβάλλει δεδομένα από αισθητήρες στον Web Browser των συσκευών μας (PC, Laptop, Tablet, κινητό), οπότε σήμερα θα δούμε πώς θα φτιάξουμε την σχετική Android εφαρμογή.
Η λογική του σχεδίου μας
Η λογική είναι η εξής, οι αισθητήρες παίρνουν δεδομένα τα οποία στέλνουν στο Arduino, το οποίο με την σειρά του τα ανεβάζει μέσω της Ethernet Shield σε έναν HTTP Server.
Στην συνέχεια η Android εφαρμογή διαβάζει τα δεδομένα αυτά από τον HTTP Server, και τα προβάλλει.
Ανάπτυξη Android εφαρμογής
Αφού εγκαταστήσετε τα απαραίτητα προγράμματα στο PC σας, και δείτε λίγο τις λειτουργίες του IDE με το παράδειγμά μας για το Hello World, είστε έτοιμοι να αρχίσετε την ανάπτυξη της εφαρμογής.
Στο νέο project μας (στην πιο απλή μορφή του) αρκεί ένα WebView το οποίο θα διαβάζει το HTML που φτιάξαμε στον Server στο Arduino.
Ενδεικτικά ο κώδικας java που μπορείτε να χρησιμοποιήσετε:
package com.sql.greekapp; import android.app.Activity; import android.os.Build; import android.os.Bundle; import android.view.KeyEvent; import android.view.Window; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import com.sql.greekapp.R; public class GreekNewsActivity extends Activity { WebView webview; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.getWindow().requestFeature(Window.FEATURE_PROGRESS); setContentView(R.layout.main); getWindow().setFeatureInt( Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON); webview = (WebView) findViewById(R.id.web_engine); webview.setWebViewClient(new HelloWebViewClient()); webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setPluginsEnabled(true); //depriciated if (Integer.parseInt(Build.VERSION.SDK) >= Build.VERSION_CODES.FROYO) webview.getSettings().setPluginState(WebSettings.PluginState.ON); webview.getSettings().setAllowFileAccess(true); webview.getSettings().setBuiltInZoomControls(true); //multitouch an ipostirizetai webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY); webview.loadUrl("http://192.168.10.250"); //o server tou Arduino //webview.loadUrl("http://google.com"); //gia debug final Activity MyActivity = this; webview.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress) { //Na svisw tin mpara afou fortwsei to url MyActivity.setTitle("Φόρτωση..."); MyActivity.setProgress(progress * 100); //svisimo // Kai na emfanisw to app name if(progress == 100) MyActivity.setTitle(R.string.app_name); } }); } //Na krataw ta clicks within the app private class HelloWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return false; } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) { webview.goBack(); return true; } return super.onKeyDown(keyCode, event); } }
Καθώς και το layout/main.xml για το UI της Android εφαρμογής:
Και το αποτέλεσμα:
Εναλλακτικές (σωστότερες) υλοποιήσεις (xml/json)
Αντί να "στήσουμε" μία ολόκληρη HTTP σελίδα στον WebServer στο Arduino, και απλά να Linkάρουμε σε αυτόν από την Android εφαρμογή μας, είναι προγραμματιστικά σωστότερο να "φτιάχνουμε" ένα xml στον server μας (ή json), το οποίο θα περιέχει τις μετρήσεις.
Στην συνέχεια θα κάνουμε "parse" το xml αυτό από την Android εφαρμογή.
Κώδικας στο Arduino για να πάρουμε xml output:
#include <SPI.h> #include <Ethernet.h> byte mac[] = { 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE }; //orizoume emeis ti mac theloume, heh! IPAddress ip(192,168,10,250); //i ip tis siskevis sto diktio, profanws rithmiste analogws EthernetServer server(80); void setup() { pinMode(4, OUTPUT); // buzzer, exodos Serial.begin(9600); while (!Serial) { ; // serial debug } Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); } void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); // standard http response header client.println("Content-Type: text/xml"); //text/xml otan theloume na vgaloume xml output client.println("Connection: close"); client.println(); client.println(""); //UTF8 giati tha xoume kai ellhnika client.println(""); client.print(""); //thermokrasia int sensorReading = analogRead(0); float temp; temp = (sensorReading * 0.488); client.print(temp); client.println(""); client.println(""); if (temp>30){ buzz(4, 2000, 4000); // energopoihsh toy buzzer sto pin 4 sta 2000Hz gia 2 sec delay(1000); // diakopi gia 1 second } break; } 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; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); Serial.println("client disonnected"); } } void buzz(int targetPin, long frequency, long length) { long delayValue = 1000000/frequency/2; long numCycles = frequency * length/ 1000; for (long i=0; i < numCycles; i++){ digitalWrite(targetPin,HIGH); delayMicroseconds(delayValue); digitalWrite(targetPin,LOW); delayMicroseconds(delayValue); } }
Κάντε Like το GreeceAndroid.gr στο Facebook!
Γίνετε μέλος της Ελληνική Κοινότητας του Android στο G+