So I've created a webserver that outputs the values from a couple of analogue sensors when a command is received from an android app. However it lags whenever any button is pressed and only occasionally works, usually crashing the app. This is the arduino code:
//ARDUINO 1.0+ ONLY
//ARDUINO 1.0+ ONLY
#include <Ethernet.h>
#include <SPI.h>
// the value of the 'other' resistor
#define SERIESRESISTOR 10000
// What pin to connect the sensor to
#define THERMISTORPIN A0
boolean reading = false;
const int analogInPin = A1;
int sensorValue = 0;
////////////////////////////////////////////////////////////////////////
//CONFIGURE
////////////////////////////////////////////////////////////////////////
byte ip[] = { 192, 168, 0, 101 }; //Manual setup only
byte gateway[] = { 192, 168, 0, 1 }; //Manual setup only
byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only
// if need to change the MAC address (Very Rare)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer server = EthernetServer(80); //port 80
////////////////////////////////////////////////////////////////////////
void setup(){
Serial.begin(9600);
//Pins 10,11,12 & 13 are used by the ethernet shield
pinMode(7, OUTPUT);
Ethernet.begin(mac, ip, gateway, subnet); //for manual setup
server.begin();
Serial.println(Ethernet.localIP());
}
void loop(){
// listen for incoming clients, and process qequest.
checkForClient();
tempReading();
}
void tempReading(){
sensorValue = analogRead(analogInPin);
EthernetClient client2 = server.available();
if (client2) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
boolean sentHeader = false;
while (client2.connected()) {
if (client2.available()) {
if(!sentHeader){
// send a standard http response header
client2.println("HTTP/1.1 200 OK");
client2.println("Content-Type: text/html");
client2.println();
sentHeader = true;
}
float reading;
reading = analogRead(THERMISTORPIN);
Serial.print("Analog reading ");-
Serial.println(reading);
// convert the value to resistance
reading = (1023 / reading) - 1;
reading = SERIESRESISTOR / reading;
Serial.print("Thermistor resistance ");
Serial.println(reading);
delay(1000);
float reading2;
char d = client2.read();
if(reading2 && d == ' ') reading2 = false;
if(d == '?') reading2 = true; //found the ?, begin reading the info
if(reading2){
switch (d) {
case '4':
//add code here to trigger on 2
client2.print("Thermistor resistance: ");
client2.println(reading);
client2.println("\n");
break;
case '5':
client2.print("Light Level: ");
client2.println(sensorValue);
client2.println("\n");
}
}
}
}
delay(1); // give the web browser time to receive the data
client2.stop(); // close the connection:
}
}
void checkForClient(){
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
boolean sentHeader = false;
while (client.connected()) {
if (client.available()) {
if(!sentHeader){
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
sentHeader = true;
}
char c = client.read();
if(reading && c == ' ') reading = false;
if(c == '?') reading = true; //found the ?, begin reading the info
if(reading){
Serial.print(c);
switch (c) {
case '1':
//add code here to trigger on 2
pinOn(7, client);
break;
case '2':
//add code here to trigger on 3
pinOff(7, client);
break;
}
}
if (c == '\n' && currentLineIsBlank) break;
if (c == '\n') {
currentLineIsBlank = true;
}else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection:
}
void pinOff(int pin, EthernetClient client){
digitalWrite(pin, HIGH);
}
void pinOn(int pin, EthernetClient client){
digitalWrite(pin, LOW);
}
and this is the Android code:
package com.example.liam.arduinocontroller;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.os.StrictMode;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
public class ControlClass extends ActionBarActivity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
StrictMode.ThreadPolicy policy = new StrictMode.
ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_control_class);
View led1on = findViewById(R.id.led_1on);
View led1off = findViewById(R.id.led_1off);
View led2on = findViewById(R.id.led_2on);
View led2off = findViewById(R.id.led_2off);
led1on.setOnClickListener(this);
led1off.setOnClickListener(this);
led2on.setOnClickListener(this);
led2off.setOnClickListener(this);
}
public void commandArduino(String url) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpParams httpParameters = httpclient.getParams();
HttpConnectionParams.setTcpNoDelay(httpParameters, true);
httpclient.execute(new HttpGet(url));
} catch (Exception e) {
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_control_class, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View thisView) {
switch(thisView.getId())
{
case R.id.led_1on:
commandArduino("http://192.168.0.101/?2");
Toast.makeText(getApplicationContext(), "led_1on", Toast.LENGTH_LONG).show();
break;
case R.id.led_1off:
commandArduino("http://192.168.0.101/?3");
Toast.makeText(getApplicationContext(), "led_1off", Toast.LENGTH_LONG).show();
break;
case R.id.led_2on:
commandArduino("http://192.168.0.101/?4");
Intent intent = new Intent(this, TempDisplay.class);
startActivity(intent);
break;
case R.id.led_2off:
commandArduino("http://192.168.0.101/?5");
Intent j = new Intent(this, LightDisplay.class);
startActivity(j);
break;
}
}
}
Any ideas?
I try to refactor your code
//ARDUINO 1.0+ ONLY
#include <Ethernet.h>
#include <SPI.h>
// the value of the 'other' resistor
#define SERIESRESISTOR 10000
// What pin to connect the sensor to
#define THERMISTORPIN A0
const int analogInPin = A1;
////////////////////////////////////////////////////////////////////////
//CONFIGURE
////////////////////////////////////////////////////////////////////////
byte ip[] = { 192, 168, 0, 101 }; //Manual setup only
byte gateway[] = { 192, 168, 0, 1 }; //Manual setup only
byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only
// if need to change the MAC address (Very Rare)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer server = EthernetServer(80); //port 80
////////////////////////////////////////////////////////////////////////
void setup(){
Serial.begin(9600);
//Pins 10,11,12 & 13 are used by the ethernet shield
pinMode(7, OUTPUT);
Ethernet.begin(mac, ip, gateway, subnet); //for manual setup
server.begin();
Serial.println(Ethernet.localIP());
}
void loop() {
boolean reading = false;
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
boolean sentHeader = false;
while (client.connected()) {
if (client.available()) {
if (!sentHeader){
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
sentHeader = true;
}
char c = client.read();
if (reading && c == ' ') {
reading = false;
}
if (c == '?') {
//found the ?, begin reading the info
reading = true;
}
if (reading){
Serial.print(c);
switch (c) {
case '1':
pinOn(7, client);
break;
case '2':
pinOff(7, client);
break;
case '4':
print_thermistor(&client);
break;
case '5':
print_light(&client);
break;
}
}
if (c == '\n' && currentLineIsBlank)
break;
if (c == '\n') {
currentLineIsBlank = true;
} else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
delay(500); // give the web browser time to receive the data
client.stop(); // close the connection:
}
}
void print_thermistor(EthernetClient *client) {
float th;
th = analogRead(THERMISTORPIN);
Serial.print("Analog th ");
Serial.println(th);
// convert the value to resistance
th = (1023 / th) - 1;
th = SERIESRESISTOR / th;
Serial.print("Thermistor resistance ");
Serial.println(th);
client->print("Thermistor resistance: ");
client->println(th);
client->println("\n");
}
void print_light(EthernetClient *client) {
int sensorValue;
sensorValue = analogRead(analogInPin);
client->print("Light Level: ");
client->println(sensorValue);
client->println("\n");
}
void pinOff(int pin, EthernetClient client){
digitalWrite(pin, HIGH);
}
void pinOn(int pin, EthernetClient client){
digitalWrite(pin, LOW);
}
Related
I'm using Android to toggle my led light with Arduino and ethernet shield. It didn't work despite having no problems during compilation neither on Android nor Arduino. I connected the ethernet shield with my computer and I gave it the same address as my computer.
This is my Android code:
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.ToggleButton;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/********************************/
/* Define all the buttons */
/********************************/
Switch led1 = (Switch) findViewById(R.id.Led1);
/*******************************************************/
/* Set an onclick/onchange listener for every button */
/*******************************************************/
led1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
/* Switch is led 1 */
new Background_get().execute("led1=1");
} else {
new Background_get().execute("led1=0");
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/*****************************************************/
/* This is a background process for connecting */
/* to the arduino server and sending */
/* the GET request withe the added data */
/*****************************************************/
private class Background_get extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
/* Change the IP to the IP you set in the arduino sketch */
URL url = new URL("http://169, 254, 128, 184/?" + params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder result = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
result.append(inputLine).append("\n");
in.close();
connection.disconnect();
return result.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
And this is the Arduino code:
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(169, 254, 128, 184);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
// Pin 5
pinMode(5, OUTPUT);
}
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;
String buffer = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
buffer += c;
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
// the connection will be closed after completion of the response
client.println("Refresh: 5");
// refresh the page automatically every 5 sec
client.println();
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
buffer = "";
} else if (c != '\r') {
if (buffer.indexOf("GET /?led1=1") >= 0) { // If led1 = 1
digitalWrite(5, HIGH); // led 1 > on
}
if (buffer.indexOf("GET /?led1=0") >= 0) { // If led1 = 0
digitalWrite(5, LOW); // led 1 > off
}
} else {
// 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 disconnected");
}
}
Program your Arduino:
#include "etherShield.h"
#include "ETHER_28J60.h"
int led2 = 7;
int led1 = 6;
static uint8_t mac[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xBB, 0xAA}; // this just needs to be unique for your network,
// so unless you have more than one of these boards
// connected, you should be fine with this value.
static uint8_t ip[4] = {192, 168, 0, 15}; // the IP address for your board. Check your home hub
// to find an IP address not in use and pick that
// this or 10.0.0.15 are likely formats for an address
// that will work.
static uint16_t port = 80; // Use port 80 - the standard for HTTP
ETHER_28J60 e;
void setup(){
e.setup(mac, ip, port);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
}
void loop(){
char* params;
if (params = e.serviceRequest()){
if (strcmp(params, "?cmd=1") == 0){digitalWrite(led1, HIGH);}
if (strcmp(params, "?cmd=2") == 0){digitalWrite(led1, LOW); }
if (strcmp(params, "?cmd=3") == 0){digitalWrite(led2, HIGH);}
if (strcmp(params, "?cmd=4") == 0){digitalWrite(led2, LOW); }
e.respond();
}
}
Program your APP
Add Permission to Your Manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
MainActivity.java
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
StrictMode.ThreadPolicy policy = new StrictMode.
ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View led1on = findViewById(R.id.led_1on);
View led1off = findViewById(R.id.led_1off);
View led2on = findViewById(R.id.led_2on);
View led2off = findViewById(R.id.led_2off);
led1on.setOnClickListener(this);
led1off.setOnClickListener(this);
led2on.setOnClickListener(this);
led2off.setOnClickListener(this);
}
public void commandArduino(String url){
try {
HttpClient httpclient = new DefaultHttpClient();
httpclient.execute(new HttpGet(url));
} catch (Exception e) {}
}
public void onClick(View thisView) {
switch(thisView.getId()){
case R.id.led_1on: commandArduino("http://192.168.0.15/?cmd=1"); break;
case R.id.led_1off: commandArduino("http://192.168.0.15/?cmd=2"); break;
case R.id.led_2on: commandArduino("http://192.168.0.15/?cmd=3"); break;
case R.id.led_2off: commandArduino("http://192.168.0.15/?cmd=4"); break;
}
}
}
Reference:
http://www.instructables.com/id/Arduino-Android-LED-control-Using-Ethernet-Shield/
Happy new year all :)
I am working on a home automation project using Arduino Uno and Android application what can communicate through my TP-Link router.
I am having a java.io.IOException: unexpected end of stream on Connection
once I send a query to the Arduino and I'm not being able to solve it.
01-01 16:51:47.771 10592-11256/com.projects.mahmoudmahdi.etherdroid E/EtherDroid: java.io.IOException: unexpected end of stream on Connection{192.168.1.215:80, proxy=DIRECT# hostAddress=192.168.1.215 cipherSuite=none protocol=http/1.1} (recycle count=0)
at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:210)
at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:904)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:788)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:443)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:501)
at com.projects.mahmoudmahdi.etherdroid.MainActivity$commandArduino.doInBackground(MainActivity.java:50)
at com.projects.mahmoudmahdi.etherdroid.MainActivity$commandArduino.doInBackground(MainActivity.java:31)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.EOFException: \n not found: size=0 content=...
at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)
at com.android.okhttp.internal.http.HttpConnection.readHeaders(HttpConnection.java:220)
at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:199)
at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:904)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:788)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:443)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:501)
at com.projects.mahmoudmahdi.etherdroid.MainActivity$commandArduino.doInBackground(MainActivity.java:50)
at com.projects.mahmoudmahdi.etherdroid.MainActivity$commandArduino.doInBackground(MainActivity.java:31)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
My Arduino Sketch:
#include <UIPEthernet.h>
int relay = 2;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 215 }; // ip in lan (that's what you need to use in your browser. (F("192.168.1.200"))
byte gateway[] = { 192, 168, 1, 10 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); //server port
String readString;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
pinMode(relay, OUTPUT);
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
Serial.print(F("server is at "));
Serial.println(Ethernet.localIP());
}
void loop() {
// Create a client connection
EthernetClient client = server.available();
if (client) {
//clearing string for next read
readString = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += c;
Serial.print(c);
}
//if HTTP request has ended
if (c == '\n') {
Serial.println(readString); //print to serial monitor for debuging
client.println("HTTP/1.1 200 OK"); //send new page
client.println("Content-Type: text/html");
//stopping client
client.stop();
//controls the Arduino if you press the buttons
if (readString.indexOf("?relay1on") > 0) {
digitalWrite(relay, LOW);
Serial.println("relay is on");
}
if (readString.indexOf("?relay1off") > 0) {
digitalWrite(relay, HIGH);
Serial.println("relay is off");
}
}
}
}
}
}
My Android Code:
package com.projects.mahmoudmahdi.etherdroid;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity implements OnClickListener {
private class commandArduino extends AsyncTask<URL, Void, Integer> {
#Override
protected Integer doInBackground(URL... url) {
int response = 0;
if (isNetworkAvailable()) {
// params comes from the execute() call: params[0] is the url.
try {
HttpURLConnection urlConnection = (HttpURLConnection) url[0].openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
switch (urlConnection.getResponseCode()) {
case HttpURLConnection.HTTP_OK:
Log.d("RESPONSE", "**OK**");
break; // fine, go on
case HttpURLConnection.HTTP_GATEWAY_TIMEOUT:
Log.d("RESPONSE", "**gateway timeout**");
break;// retry
case HttpURLConnection.HTTP_UNAVAILABLE:
Log.d("RESPONSE", "**unavailable**");
break;// retry, server is unstable
default:
Log.d("RESPONSE", "**unknown response code**.");
break; // abort
}
urlConnection.disconnect();
Log.d("RESPONSE", "Aborting download of dataset.");
} catch (Exception e) {
Log.e("EtherDroid", "STACKTRACE");
Log.e("EtherDroid", Log.getStackTraceString(e));
}
}
return response;
}
}
static boolean relay1 = false;
commandArduino cmdAdn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button Relay1 = (Button) findViewById(R.id.relay1);
Relay1.setOnClickListener(this);
}
private boolean isNetworkAvailable() {
boolean available = false;
/** Getting the system's connectivity service */
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
/** Getting active network interface to get the network's status */
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable())
available = true;
/** Returning the status of the network */
return available;
}
public void onClick(View thisView) {
cmdAdn = new commandArduino();
switch (thisView.getId()) {
case R.id.relay1:
if (!relay1) {
relay1 = true;
try {
cmdAdn.execute(new URL("http://192.168.1.215/?relay1on"));
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "relay1 on", Toast.LENGTH_SHORT).show();
} else {
relay1 = false;
try {
cmdAdn.execute(new URL("http://192.168.1.215/?relay1off"));
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "relay1 off", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
In general terms, you're missing:
Send data in the response
Giving time for the socket to send data before closing
Reading Android's response before closing the connection.
More in detail, make sure to send some data after establishing the connection:
client.println("HTTP/1.1 200 OK"); //send new page
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("</html>");
// Give it time to close
delay(1);
client.close();
Reference: https://www.arduino.cc/en/Tutorial/WebServer , here's the full example:
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(); // NOTE: You're missing this in your code
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("<br />");
}
client.println("</html>");
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 disconnected");
Ethernet.maintain();
}
}
Also, consider using json instead of html for Arduino's response. To do that, you'll need to change:
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: application/json");
client.println("Connection: close");
client.println();
client.println("{\"status\":\"ok\"}"); // Or whatever you want to change
I want to connect the VPN in my Application.
I download the demo from https://github.com/guardianproject/OrbotVPN
package org.torproject.android.vpn;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.VpnService;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
import com.runjva.sourceforge.jsocks.protocol.ProxyServer;
import com.runjva.sourceforge.jsocks.server.ServerAuthenticatorNone;
public class OrbotVpnService extends VpnService implements Handler.Callback, Runnable {
private static final String TAG = "OrbotVpnService";
private String mServerAddress = "192.xx.xx.xx";
private int mServerPort = xxxx;
private PendingIntent mConfigureIntent;
private Handler mHandler;
private Thread mThread;
private String mSessionName = "OrbotVPN";
private ParcelFileDescriptor mInterface;
private int mSocksProxyPort = 9999;
private boolean mKeepRunning = true;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The handler is only used to show messages.
if (mHandler == null) {
mHandler = new Handler(this);
}
// Stop the previous session by interrupting the thread.
if (mThread != null) {
mThread.interrupt();
}
// Start a new session by creating a new thread.
mThread = new Thread(this, "OrbotVpnThread");
mThread.start();
startSocksBypass ();
return START_STICKY;
}
private void startSocksBypass ()
{
Thread thread = new Thread ()
{
public void run ()
{
try {
final ProxyServer server = new ProxyServer(new ServerAuthenticatorNone(null, null));
server.setVpnService(OrbotVpnService.this);
server.start(9999, 5, InetAddress.getLocalHost());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
};
thread.start();
}
#Override
public void onDestroy() {
if (mThread != null) {
mKeepRunning = false;
mThread.interrupt();
}
}
#Override
public boolean handleMessage(Message message) {
if (message != null) {
Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show();
}
return true;
}
#Override
public synchronized void run() {
try {
Log.i(TAG, "Starting");
// If anything needs to be obtained using the network, get it now.
// This greatly reduces the complexity of seamless handover, which
// tries to recreate the tunnel without shutting down everything.
// In this demo, all we need to know is the server address.
InetSocketAddress server = new InetSocketAddress(
mServerAddress, mServerPort);
mHandler.sendEmptyMessage(R.string.connecting);
run(server);
} catch (Exception e) {
Log.e(TAG, "Got " + e.toString());
try {
mInterface.close();
} catch (Exception e2) {
// ignore
}
mHandler.sendEmptyMessage(R.string.disconnected);
} finally {
}
}
/*
#Override
public synchronized void run() {
try {
Log.i(TAG, "Starting");
// If anything needs to be obtained using the network, get it now.
// This greatly reduces the complexity of seamless handover, which
// tries to recreate the tunnel without shutting down everything.
// In this demo, all we need to know is the server address.
InetSocketAddress server = new InetSocketAddress(
mServerAddress, mServerPort);
// We try to create the tunnel for several times. The better way
// is to work with ConnectivityManager, such as trying only when
// the network is avaiable. Here we just use a counter to keep
// things simple.
for (int attempt = 0; attempt < 10; ++attempt) {
mHandler.sendEmptyMessage(R.string.connecting);
// Reset the counter if we were connected.
if (run(server)) {
attempt = 0;
}
// Sleep for a while. This also checks if we got interrupted.
Thread.sleep(3000);
}
Log.i(TAG, "Giving up");
} catch (Exception e) {
Log.e(TAG, "Got " + e.toString());
} finally {
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
mInterface = null;
mHandler.sendEmptyMessage(R.string.disconnected);
Log.i(TAG, "Exiting");
}
}*/
DatagramChannel mTunnel = null;
private boolean run(InetSocketAddress server) throws Exception {
boolean connected = false;
// Create a DatagramChannel as the VPN tunnel.
mTunnel = DatagramChannel.open();
DatagramSocket s = mTunnel.socket();
// Protect the tunnel before connecting to avoid loopback.
if (!protect(s)) {
throw new IllegalStateException("Cannot protect the tunnel");
}
mTunnel.connect(server);
// For simplicity, we use the same thread for both reading and
// writing. Here we put the tunnel into non-blocking mode.
mTunnel.configureBlocking(false);
// Authenticate and configure the virtual network interface.
handshake();
// Now we are connected. Set the flag and show the message.
connected = true;
mHandler.sendEmptyMessage(R.string.connected);
new Thread ()
{
public void run ()
{
// Allocate the buffer for a single packet.
ByteBuffer packet = ByteBuffer.allocate(32767);
// Packets to be sent are queued in this input stream.
FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
// Packets received need to be written to this output stream.
FileOutputStream out = new FileOutputStream(mInterface.getFileDescriptor());
// We use a timer to determine the status of the tunnel. It
// works on both sides. A positive value means sending, and
// any other means receiving. We start with receiving.
int timer = 0;
Log.d(TAG,"tunnel open:" + mTunnel.isOpen() + " connected:" + mTunnel.isConnected());
// We keep forwarding packets till something goes wrong.
while (true) {
try
{
// Assume that we did not make any progress in this iteration.
boolean idle = true;
// Read the outgoing packet from the input stream.
int length = in.read(packet.array());
if (length > 0) {
Log.d(TAG,"got outgoing packet; length=" + length);
// Write the outgoing packet to the tunnel.
packet.limit(length);
mTunnel.write(packet);
packet.clear();
// There might be more outgoing packets.
idle = false;
// If we were receiving, switch to sending.
if (timer < 1) {
timer = 1;
}
}
// Read the incoming packet from the mTunnel.
length = mTunnel.read(packet);
if (length > 0) {
Log.d(TAG,"got inbound packet; length=" + length);
// Write the incoming packet to the output stream.
out.write(packet.array(), 0, length);
packet.clear();
// There might be more incoming packets.
idle = false;
// If we were sending, switch to receiving.
if (timer > 0) {
timer = 0;
}
}
// If we are idle or waiting for the network, sleep for a
// fraction of time to avoid busy looping.
if (idle) {
Thread.sleep(100);
// Increase the timer. This is inaccurate but good enough,
// since everything is operated in non-blocking mode.
timer += (timer > 0) ? 100 : -100;
// We are receiving for a long time but not sending.
if (timer < -15000) {
// Switch to sending.
timer = 1;
}
// We are sending for a long time but not receiving.
if (timer > 20000) {
//throw new IllegalStateException("Timed out");
//Log.d(TAG,"receiving timed out? timer=" + timer);
}
}
}
catch (Exception e)
{
Log.d(TAG,"error in tunnel",e);
}
}
}
}.start();
return connected;
}
private void handshake() throws Exception {
if (mInterface == null)
{
Builder builder = new Builder();
builder.setMtu(1500);
builder.addAddress("10.0.2.0",24);
builder.setSession("OrbotVPN");
builder.addRoute("0.0.0.0",0);
builder.addDnsServer("8.8.8.8");
// builder.addDnsServer("127.0.0.1:5400");
// Close the old interface since the parameters have been changed.
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
// Create a new interface using the builder and save the parameters.
mInterface = builder.setSession(mSessionName)
.setConfigureIntent(mConfigureIntent)
.establish();
}
}
private void debugPacket(ByteBuffer packet)
{
/*
for(int i = 0; i < length; ++i)
{
byte buffer = packet.get();
Log.d(TAG, "byte:"+buffer);
}*/
int buffer = packet.get();
int version;
int headerlength;
version = buffer >> 4;
headerlength = buffer & 0x0F;
headerlength *= 4;
Log.d(TAG, "IP Version:"+version);
Log.d(TAG, "Header Length:"+headerlength);
String status = "";
status += "Header Length:"+headerlength;
buffer = packet.get(); //DSCP + EN
buffer = packet.getChar(); //Total Length
Log.d(TAG, "Total Length:"+buffer);
buffer = packet.getChar(); //Identification
buffer = packet.getChar(); //Flags + Fragment Offset
buffer = packet.get(); //Time to Live
buffer = packet.get(); //Protocol
Log.d(TAG, "Protocol:"+buffer);
status += " Protocol:"+buffer;
buffer = packet.getChar(); //Header checksum
String sourceIP = "";
buffer = packet.get(); //Source IP 1st Octet
sourceIP += buffer;
sourceIP += ".";
buffer = packet.get(); //Source IP 2nd Octet
sourceIP += buffer;
sourceIP += ".";
buffer = packet.get(); //Source IP 3rd Octet
sourceIP += buffer;
sourceIP += ".";
buffer = packet.get(); //Source IP 4th Octet
sourceIP += buffer;
Log.d(TAG, "Source IP:"+sourceIP);
status += " Source IP:"+sourceIP;
String destIP = "";
buffer = packet.get(); //Destination IP 1st Octet
destIP += buffer;
destIP += ".";
buffer = packet.get(); //Destination IP 2nd Octet
destIP += buffer;
destIP += ".";
buffer = packet.get(); //Destination IP 3rd Octet
destIP += buffer;
destIP += ".";
buffer = packet.get(); //Destination IP 4th Octet
destIP += buffer;
Log.d(TAG, "Destination IP:"+destIP);
status += " Destination IP:"+destIP;
/*
msgObj = mHandler.obtainMessage();
msgObj.obj = status;
mHandler.sendMessage(msgObj);
*/
//Log.d(TAG, "version:"+packet.getInt());
//Log.d(TAG, "version:"+packet.getInt());
//Log.d(TAG, "version:"+packet.getInt());
}
}
It also connected with VPN and show the key symbol on top of the bar, but dont found any server entry in my server Interfaces.Same server I register in mobile network it Connected and I found the Server entry in my server Interfaces.
Is there any server Implementation require?
Am I wrong in above VPN service or I make the mistake in it?
Is there other way for connecting the VPN using the Username,password and server Id?
Try this :
void startVPN(String name) {
Intent i=new Intent("doenter.onevpn.ACTION_CONNECT");
i.putExtra("name",name);
i.putExtra("force", true);
i.putExtra("force_same", false);
startActivity(i);
}
void restartVPN(String name) {
Intent i=new Intent("doenter.onevpn.ACTION_CONNECT");
i.putExtra("name",name);
i.putExtra("force", true);
i.putExtra("force_same", true);
startActivity(i);
}
void stopVPN() {
Intent i=new Intent("doenter.onevpn.ACTION_DISCONNECT");
// Stops any VPN regardless of name
startActivity(i);
}
I've created an Android app to communicate with my Arduino using Bluetooth. But when I'm sending data from my Android device to my Arduino, the Arduino isn't responding to what I've send. I am able to get a connection from my Android device to my Arduino. So that's not the problem.
Here's my full script for Android.
package nl.handoko.LumaMini;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "LumaMini";
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
Button fourty, thirty, twenty, twelve, automatic, manual;
TextView message;
// Well known SPP UUID
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Server's MAC address
private static String address = "98:D3:31:30:09:43";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "In onCreate()");
setContentView(R.layout.activity_mainnn);
fourty = (Button) findViewById(R.id.button1);
thirty = (Button) findViewById(R.id.button4);
twenty = (Button) findViewById(R.id.button2);
twelve = (Button) findViewById(R.id.button5);
automatic = (Button) findViewById(R.id.button3);
manual = (Button) findViewById(R.id.button6);
message = (TextView) findViewById(R.id.textView1);
fourty.setText("40 Leds");
thirty.setText("30 Leds");
twenty.setText("20 Leds");
twelve.setText("12 Leds");
automatic.setText("Automatic");
manual.setText("Manual");
message.setText("Using this app you can take full control of the Luma Mini!" +
"When it's running on automatic please switch back to manual first before switching to other versions.");
btAdapter = BluetoothAdapter.getDefaultAdapter();
checkBTState();
fourty.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
sendData("a");
Toast msg = Toast.makeText(getBaseContext(),
"40 Leds version", Toast.LENGTH_SHORT);
msg.show();
}
});
thirty.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
sendData("b");
Toast msg = Toast.makeText(getBaseContext(),
"30 Leds version", Toast.LENGTH_SHORT);
msg.show();
}
});
twenty.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
sendData("c");
Toast msg = Toast.makeText(getBaseContext(),
"20 Leds version", Toast.LENGTH_SHORT);
msg.show();
}
});
twelve.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
sendData("d");
Toast msg = Toast.makeText(getBaseContext(),
"12 Leds version", Toast.LENGTH_SHORT);
msg.show();
}
});
automatic.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
sendData("e");
Toast msg = Toast.makeText(getBaseContext(),
"Run automatically", Toast.LENGTH_SHORT);
msg.show();
}
});
manual.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
sendData("f");
Toast msg = Toast.makeText(getBaseContext(),
"Manually switch Leds", Toast.LENGTH_SHORT);
msg.show();
}
});
}
#Override
public void onResume() {
super.onResume();
Log.d(TAG, "...In onResume - Attempting client connect...");
// Set up a pointer to the remote node using it's address.
BluetoothDevice device = btAdapter.getRemoteDevice(address);
// Two things are needed to make a connection:
// A MAC address, which we got above.
// A Service ID or UUID. In this case we are using the
// UUID for SPP.
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}
// Discovery is resource intensive. Make sure it isn't going on
// when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();
// Establish the connection. This will block until it connects.
Log.d(TAG, "...Connecting to Remote...");
try {
btSocket.connect();
Log.d(TAG, "...Connection established and data link opened...");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
}
}
// Create a data stream so we can talk to server.
Log.d(TAG, "...Creating Socket...");
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
}
}
#Override
public void onPause() {
super.onPause();
Log.d(TAG, "...In onPause()...");
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
errorExit("Fatal Error", "In onPause() and failed to flush output stream: " + e.getMessage() + ".");
}
}
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
}
}
private void checkBTState() {
// Check for Bluetooth support and then check to make sure it is turned on
// Emulator doesn't support Bluetooth and will return null
if(btAdapter==null) {
errorExit("Fatal Error", "Bluetooth Not supported. Aborting.");
} else {
if (btAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth is enabled...");
} else {
//Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
}
private void errorExit(String title, String message){
Toast msg = Toast.makeText(getBaseContext(),
title + " - " + message, Toast.LENGTH_SHORT);
msg.show();
finish();
}
private void sendData(String message) {
byte[] msgBuffer = message.getBytes();
Log.d(TAG, "...Sending data: " + message + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
msg = msg + ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";
errorExit("Fatal Error", msg);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And here's my Arduino script:
#include <SoftwareSerial.h>
#include <TimerOne.h>
#define Rx 2
#define Tx 3
#define seconds 4
char serialData; // Serial data memory
int counter1; // Overflow memory
int action; // Action trigger
int once = 0; // Run only once
SoftwareSerial Bluetooth(Rx, Tx);
void setup(){
pinMode(Tx, OUTPUT); // Configure Tx as OUTPUT (Transmitter)
pinMode(Rx, INPUT);
delay(1000);
Bluetooth.begin(9600);
Serial.begin(1200);
delay(1000);
Serial.print("Bluetooth ready");
Bluetooth.flush();
TimerOneSetup(); // Run the setup for Timer One
for(int i = 5; i <= 8; i++){ // Make pins 5, 6, 7 and 8 OUTPUT
pinMode(i, OUTPUT);
}
}
void interrupt1(){ // Timer One loop
counter1++; // Count the amount of seconds has passed
if (counter1 == seconds){ // Trigger the next action after a several amount of seconds (Default: 4 seconds)
action++;
counter1 = 0;
}
if (action > 3){ // Reset action trigger when after all actions were runned
action = 0;
}
}
void loop(){ // Endless loop
if (Serial.available()){ // Wait for data recieved from Local device
serialData = Serial.read(); // Put recieved data in memory
Serial.print("Data recieved from Local device: ");
Serial.println(serialData);
}
if (Bluetooth.available()){ // Wait for data recieved from Bluetooth device
serialData = Bluetooth.read(); // Put recieved data in memory
Serial.print("Data recieved from Bluetooth device: ");
Serial.print(serialData);
}
if (once == 0){ // This script will be run only once
serialData = 'e'; // Put switch on automatic on startup
once++; // Get into the next stage which may be run only once
}
switch(serialData){ // Perform action on state of the switch
case 'a':
fourtyLeds(); // Show the 40 Leds version of the Luma Mini
break;
case 'b':
thirtyLeds(); // Show the 30 Leds version of the Luma Mini
break;
case 'c':
twentyLeds(); // Show the 20 Leds version of the Luma Mini
break;
case 'd':
twelveLeds(); // Show the 12 Leds version of the Luma Mini
break;
case 'e':
while(serialData == 'e'){ // Keep changing different Led versions of the Luma Mini automatically
switch(action){
case 0: // Wait for the action trigger to hit the first action
fourtyLeds(); // Show the 40 Leds version of the Luma Mini
break;
case 1: // Wait for the action trigger to hit the second action
twelveLeds(); // Show the 12 Leds version of the Luma Mini
break;
case 2: // Wait for the action trigger to hit the third action
twentyLeds(); // Show the 20 Leds version of the Luma Mini
break;
case 4: // Wait for the action trigger to hit the fourth action
thirtyLeds(); // Show the 30 Leds version of the Luma Mini
break;}
if (Serial.read() == 'f'){ // Wait for data recieved from Local device
serialData = Serial.read(); // Put recieved data in memory
Serial.print("Data recieved from Local device: ");
Serial.println(serialData);
}
if (Bluetooth.read() == 'f'){ // Wait for data recieved from Bluetooth device
serialData = Bluetooth.read(); // Put recieved data in memory
Serial.print("Data recieved from Bluetooth device: ");
Serial.println(serialData);
}
break;
}
}
}
void BluetoothSetup(){
pinMode(Tx, OUTPUT); // Configure Tx as OUTPUT (Transmitter)
pinMode(Rx, INPUT); // Configure Rx as INPUT (Reciever)
Bluetooth.begin(9600); // Set Bluetooth baud rate to default baud rate 38400
Bluetooth.print("\r\n+STWMOD=0\r\n"); // Set the Bluetooth to work in slave mode
Bluetooth.print("\r\n+STNA=Luma Mini\r\n"); // Set Bluetooth name to Luma Mini
Bluetooth.print("\r\n+STOAUT=1\r\n"); // Permit paired device to connect
Bluetooth.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000);
Bluetooth.print("\r\n+INQ=1\r\n"); // Make this Bluetooth Slave inquirable
Serial.println("The slave Bluetooth is inquirable!");
delay(2000);
Bluetooth.flush();
}
void TimerOneSetup(){
Timer1.initialize(1000000); // Initialize Timer One for an overflow exactly every 1 second
Timer1.attachInterrupt(interrupt1); // Open the Timer One loop
}
void fourtyLeds(){ // Show the 40 Leds version of the Luma Mini
for(int i = 5; i <= 8; i++){
digitalWrite(i, LOW);
}
}
void thirtyLeds(){ // Show the 30 Leds version of the Luma Mini
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
}
void twentyLeds(){ // Show the 20 Leds version of the Luma Mini
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
}
void twelveLeds(){ // Show the 12 Leds version of the Luma Mini
for (int i = 5; i <= 8; i++){
digitalWrite(i, HIGH);
}
}
My question: How can I send CHAR data from an Android Device to my Arduino? And what to edit on my script?
I have not gone through your code. But looking at the question, I suggests to keep Arduino FW coding away till Android app is tested and developed to a certain level. The way forward could be:
Disconnect HC-06 from other hardware.
Make a loopback connection at HC-06 (i.e Connect TX & RX outputs of HC-06 together.
Then Test your Android application. If app is receiving same as transmitted, then your android app is ok, and you can move on perfecting Arduino FW. Else, the android app needs to be perfected.
You can have a look at a similar question HC-05 bluetooth module on Arduino + Debugging .
Here's the code I use, and it works fine for me.
On the Android side, I'm only including my bluetooth file, which should be easy to fit into your app. It's main advantage is that after your app start it by calling btConnect(), everything else is automatic. It finds and connects to your "HC-06" without further "human intervention". And if you turn off the "HC-06", Android will continue watching for the "HC-06" to come back online, and will auto-connect to it again.
The Arduino Sketch sends a signal once each second. If 10 seconds are missed, the Android assumes the connection has been lost and re-enters connect mode.
ANDROID BLUETOOTH JAVA FILE:
package com.exercise.androidanimbuttons;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.IntentFilter;
import android.widget.Toast;
import android.bluetooth.BluetoothSocket;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import java.util.Set;
import android.os.Handler;
public class BlueTooth extends vars {
private Set<BluetoothDevice> pairedDevices;
String address = null;
private ProgressDialog progress = null;
BluetoothAdapter myBluetooth = null;
BluetoothSocket btSocket = null;
InputStream mmInStream = null;
private Handler myHandler = new Handler();
byte[] buffer = new byte[25];
int readBytes;
files filesI = new files();
Handler btH = new Handler();
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private SingBroadcastReceiver mReceiver;
Runnable btSearch;
void stopDiscovery() {
if (myBluetooth.isDiscovering()){
myBluetooth.cancelDiscovery();
}
}
void findCurrentBT() {
if (!myBluetooth.isEnabled()){
Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBT, 0xDEADBEEF);
}
if (myBluetooth.isDiscovering()){
myBluetooth.cancelDiscovery();
}
closeProgress();
progress = ProgressDialog.show(BlueTooth.this, "Searching for headband...",
"MAKE SURE THE HEADBAND IS TURNED ON.");
progress.setCanceledOnTouchOutside(true);
myBluetooth.startDiscovery();
mReceiver = new SingBroadcastReceiver();
IntentFilter ifilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, ifilter);
checkSearch();
}
private class SingBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String derp = device.getName() + " - " + device.getAddress();
ta(derp);
Toast.makeText(context, derp, Toast.LENGTH_LONG);
if ((device.getName() != null) &&
(device.getName().indexOf("HC-06") == 0) &&
(device.getName().length() == 5))
{
myBluetooth.cancelDiscovery();
address = device.getAddress();
new ConnectBT().execute();
}
}
}
}
private Runnable readBT = new Runnable() {
public void run() {
int i;
int twoByte = 0;
short high = 0, low = 0;
try {
if (mmInStream.available() > 3) {
cnt = 0;
readBytes = mmInStream.read(buffer);
String S = "";
for (i = 0; i < 2; i++)
S += String.format("%03d", buffer[i] & 0xFF)+", ";
high = (short)(buffer[3] & 0xFF);
low = (short)(buffer[2] & 0xFF);
twoByte = ((high << 8) | low);
S += String.format("%03d", twoByte) + "\r\n";
filesI.writeALine("nights","data12.txt",S);
ta(S);
}
} catch (IOException e) {
ta("err:2 " + e.toString());
}
if (btSocket.isConnected())
myHandler.postDelayed(this, 100);
}
};
public void btConnect() {
Disconnect();
findCurrentBT();
}
public void btOn() {
turnOnLed();
}
public void btOff() { turnOffLed(); }
public void btDisconnect() { Disconnect(); }
private void Disconnect()
{
if (btSocket!=null)
{
try
{
btSocket.close();
}
catch (IOException e)
{ msg("Bluetooth Disconnect Error");}
}
}
private void turnOffLed()
{
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write("TF".toString().getBytes());
}
catch (IOException e)
{
msg("Error");
}
}
}
private void turnOnLed()
{
int len;
byte[] buffer = new byte[400];
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write("TO".toString().getBytes());
len = btSocket.getInputStream().available();
btSocket.getInputStream().read(buffer,0,len);
}
catch (IOException e)
{
msg("Error");
}
}
}
private void msg(String s)
{
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
void closeProgress() {
if (progress != null)
progress.dismiss();
}
private class ConnectBT extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute()
{
closeProgress();
progress = ProgressDialog.show(BlueTooth.this, "Connecting to headband...",
"");
progress.setCanceledOnTouchOutside(true);
}
#Override
protected Void doInBackground(Void... devices)
{
try
{
if (btSocket == null || (!btSocket.isConnected()))
{
BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);
btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();
}
}
catch (IOException e) { }
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
if (!btSocket.isConnected())
{
msg("Connection Failed. Is the headband turned on?");
}
else
{
msg("Connected.");
try {
mmInStream = btSocket.getInputStream();
myHandler.postDelayed(readBT, 1000);
} catch (IOException e) {
ta("err:1 " + e.toString());
}
}
closeProgress();
}
}
int cnt = 0;
void checkSearch() {
if (btSearch != null)
return;
btSearch = new Runnable(){#Override public void run(){
if ((btSocket != null) && (btSocket.isConnected())) {
cnt--;
if (cnt < -10) {
cnt = 0;
btConnect();
}
} else if (myBluetooth.isDiscovering()) {
cnt++;
}
btH.postDelayed(this, 1000);
fa(cnt);
}};
btH.postDelayed(btSearch,1000);
}
}
MATCHING ARDUINO SKETCH:
byte mini [4];
int battery;
unsigned long mill = millis();
byte moveCnt = 1;
int minuteCnt = 0;
int lastMove = 0;
int moveA, moveB, moveC, LMoveA, LMoveB, LMoveC, totMove, eyes, LEyes, totEyes;
int moveUpA = 0;
int moveDnA = 1000;
int moveUpB = 0;
int moveDnB = 1000;
int moveUpC = 0;
int moveDnC = 1000;
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 5); // RX, TX
void setup()
{
Serial .begin(9600);
mySerial.begin(9600);
}
void loop()
{
if (millis() > mill)
{
mill += 100;
minuteCnt++;
// *** EYES ***
eyes = analogRead(A6);
totEyes += abs(eyes-LEyes);
LEyes = eyes;
// *** MOVEMENT *** --KEEP-- moveA = max(0,analogRead(A1) >> 2);
moveA = analogRead(A0);
moveB = analogRead(A1);
moveC = analogRead(A2);
totMove += abs(moveA-LMoveA) + abs(moveB-LMoveB) + abs(moveC-LMoveC);
LMoveA = moveA; LMoveB = moveB; LMoveC = moveC;
// *** SEND SECOND ***
if (minuteCnt >= 10)
{
minuteCnt = 0;
// *** BATTERY ***
battery = analogRead(A5); // battery
mini[2] = (battery & 0xff); // battery low byte
mini[3] = ((battery >> 8) & 0xff); // battery high byte
// *** EYES ***
mini[0] = min(max(0,totEyes-10),255);
totEyes = 0;
// *** MOVEMENT ***
mini[1] = min(max(0,totMove-30),255);
totMove = 0;
Serial.print(mini[0]);
Serial.print(" ");
Serial.print(mini[1]);
Serial.print(" ");
Serial.print(mini[2]);
Serial.print(" ");
Serial.println(mini[3]);
mySerial.write(mini,4);
}
}
}
So I'm trying to communicate with an Arduino Uno through an HC-06 chip, but the SoftwareSerial isn't available for reading, even after a connection has been established. The Processing code was mainly taken from this article:
http://arduinobasics.blogspot.com/2013/03/arduinobasics-bluetooth-android_25.html
Can anyone help me out with this and tell me where the problem lies?
Processing Code:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.Toast;
import android.view.Gravity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import java.util.UUID;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
public BluetoothSocket scSocket;
boolean foundDevice=false; //When true, the screen turns green.
boolean BTisConnected=false; //When true, the screen turns purple.
String serverName = "ArduinoBasicsServer";
// Message types used by the Handler
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_READ = 2;
String readMessage="";
//Get the default Bluetooth adapter
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
/*The startActivityForResult() within setup() launches an
Activity which is used to request the user to turn Bluetooth on.
The following onActivityResult() method is called when this
Activity exits. */
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode==0) {
if (resultCode == RESULT_OK) {
ToastMaster("Bluetooth has been switched ON");
}
else {
ToastMaster("You need to turn Bluetooth ON !!!");
}
}
}
/* Create a BroadcastReceiver that will later be used to
receive the names of Bluetooth devices in range. */
BroadcastReceiver myDiscoverer = new myOwnBroadcastReceiver();
/* Create a BroadcastReceiver that will later be used to
identify if the Bluetooth device is connected */
BroadcastReceiver checkIsConnected = new myOwnBroadcastReceiver();
// The Handler that gets information back from the Socket
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_WRITE:
//Do something when writing
break;
case MESSAGE_READ:
//Get the bytes from the msg.obj
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
readMessage = new String(readBuf, 0, msg.arg1);
break;
}
}
};
void setup() {
orientation(LANDSCAPE);
/*IF Bluetooth is NOT enabled, then ask user permission to enable it */
if (!bluetooth.isEnabled()) {
Intent requestBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(requestBluetooth, 0);
}
/*If Bluetooth is now enabled, then register a broadcastReceiver to report any
discovered Bluetooth devices, and then start discovering */
if (bluetooth.isEnabled()) {
registerReceiver(myDiscoverer, new IntentFilter(BluetoothDevice.ACTION_FOUND));
registerReceiver(checkIsConnected, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
//Start bluetooth discovery if it is not doing so already
if (!bluetooth.isDiscovering()) {
bluetooth.startDiscovery();
}
}
}
void draw() {
//Display a green screen if a device has been found,
//Display a purple screen when a connection is made to the device
if (foundDevice) {
if (BTisConnected) {
background(170, 50, 255); // purple screen
}
else {
background(10, 255, 10); // green screen
}
}
//Display anything received from Arduino
text(readMessage, 10, 10);
}
/* This BroadcastReceiver will display discovered Bluetooth devices */
public class myOwnBroadcastReceiver extends BroadcastReceiver {
ConnectToBluetooth connectBT;
#Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
ToastMaster("ACTION:" + action);
//Notification that BluetoothDevice is FOUND
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//Display the name of the discovered device
String discoveredDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
ToastMaster("Discovered: " + discoveredDeviceName);
//Display more information about the discovered device
BluetoothDevice discoveredDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if(discoveredDevice.getName()=="HC-06"){
ToastMaster("getAddress() = " + discoveredDevice.getAddress());
ToastMaster("getName() = " + discoveredDevice.getName());
int bondyState=discoveredDevice.getBondState();
ToastMaster("getBondState() = " + bondyState);
String mybondState;
switch(bondyState) {
case 10:
mybondState="BOND_NONE";
break;
case 11:
mybondState="BOND_BONDING";
break;
case 12:
mybondState="BOND_BONDED";
break;
default:
mybondState="INVALID BOND STATE";
break;
}
ToastMaster("getBondState() = " + mybondState);
}
//Change foundDevice to true which will make the screen turn green
foundDevice=true;
//Connect to the discovered bluetooth device (SeeedBTSlave)
if (discoveredDeviceName.equals("HC-06")) {
ToastMaster("Connecting you Now !!");
unregisterReceiver(myDiscoverer);
connectBT = new ConnectToBluetooth(discoveredDevice);
//Connect to the the device in a new thread
new Thread(connectBT).start();
}
}
//Notification if bluetooth device is connected
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
ToastMaster("CONNECTED _ YAY");
while (scSocket==null) {
//do nothing
}
ToastMaster("scSocket " + scSocket);
BTisConnected=true; //turn screen purple
if (scSocket!=null) {
SendReceiveBytes sendReceiveBT = new SendReceiveBytes(scSocket);
new Thread(sendReceiveBT).start();
String red = "r";
byte[] myByte = stringToBytesUTFCustom(red);
sendReceiveBT.write(myByte);
}
}
}
}
public static byte[] stringToBytesUTFCustom(String str) {
char[] buffer = str.toCharArray();
byte[] b = new byte[buffer.length << 1];
for (int i = 0; i < buffer.length; i++) {
int bpos = i << 1;
b[bpos] = (byte) ((buffer[i]&0xFF00)>>8);
b[bpos + 1] = (byte) (buffer[i]&0x00FF);
}
return b;
}
public class ConnectToBluetooth implements Runnable {
private BluetoothDevice btShield;
private BluetoothSocket mySocket = null;
private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public ConnectToBluetooth(BluetoothDevice bluetoothChip) {
btShield = bluetoothChip;
try {
mySocket = btShield.createRfcommSocketToServiceRecord(uuid);
}
catch(IOException createSocketException) {
//Problem with creating a socket
Log.e("ConnectToBluetooth", "Error with Socket");
}
}
#Override
public void run() {
/* Cancel discovery on Bluetooth Adapter to prevent slow connection */
bluetooth.cancelDiscovery();
try {
/*Connect to the bluetoothShield through the Socket. This will block
until it succeeds or throws an IOException */
mySocket.connect();
scSocket=mySocket;
}
catch (IOException connectException) {
Log.e("ConnectToBluetooth", "Error with Socket Connection");
try {
mySocket.close(); //try to close the socket
}
catch(IOException closeException) {
}
return;
}
}
/* Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mySocket.close();
}
catch (IOException e) {
}
}
}
private class SendReceiveBytes implements Runnable {
private BluetoothSocket btSocket;
private InputStream btInputStream = null;
private OutputStream btOutputStream = null;
public SendReceiveBytes(BluetoothSocket socket) {
btSocket = socket;
try {
btInputStream = btSocket.getInputStream();
btOutputStream = btSocket.getOutputStream();
}
catch (IOException streamError) {
println("Error when getting input or output Stream");
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = btInputStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
}
catch (IOException e) {
println("Error reading from btInputStream");
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
btOutputStream.write(bytes);
}
catch (IOException e) {
println("Error when writing to btOutputStream");
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
btSocket.close();
}
catch (IOException e) {
println("Error when closing the btSocket");
}
}
}
/* My ToastMaster function to display a messageBox on the screen */
void ToastMaster(String textToDisplay) {
Toast myMessage = Toast.makeText(getApplicationContext(),
textToDisplay,
Toast.LENGTH_SHORT);
myMessage.setGravity(Gravity.CENTER, 0, 0);
myMessage.show();
}
Arduino Code:
int data;
char character;
int start_flag = 0;
#include <SoftwareSerial.h>
int bluetoothTx = 3;
int bluetoothRx = 2;
SoftwareSerial blue = SoftwareSerial(bluetoothRx, bluetoothTx);
void setup(){
blue.begin(9600);
pinMode(13, OUTPUT);
pinmode(bluetoothRx, INPUT);
pinmode(bluetoothTx, OUTPUT);
digitalWrite(13, LOW);
}
void loop() {
if (blue.available() > 0) {
digitalWrite(13, HIGH);
character = (char) blue.read();
if (character != '#') {
start_flag = 1;
}
if(character == 't'){
start_flag = 0;
}
} else {
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
}
if (start_flag == 1) {
//digitalWrite(13, HIGH);
blue.print(data); //data that was acquired by internal ADC
}
}
I think you need to change the order of your lines within the Arduino setup() code:
And you also need some code to initialise your bluetooth module.
This is what I think you need to change it to:
void setup(){
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
pinmode(bluetoothRx, INPUT);
pinmode(bluetoothTx, OUTPUT);
//You may need to modify this to suit your bluetooth module
//This is used to initialise the bluetooth module
blue.begin(9600); //*************
blue.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
blue.print("\r\n+STNA=SeeedBTSlave\r\n"); //set the bluetooth name as "SeeedBTSlave"
blue.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
blue.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000); // This delay is required.
blue.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
delay(2000); // This delay is required.
blue.flush();
}
Hello i used to same code from #ScottC :)
its old post but maybe someone will have same problem anytime .
the problem is blue.print("\r\n+STNA=SeeedBTSlave\r\n"); //set the bluetooth name as "SeeedBTSlave"
change it to
blue.print("\r\n+STNA=HC-06\r\n"); //set the bluetooth name as "SeeedBTSlave"
"OR CHANGE IT AS YOUR BLUETOOTH DEVICE NAME . ( i assumed is HC-06)
pinmode(bluetoothRx, INPUT);
pinmode(bluetoothTx, OUTPUT);
Capital "M" in pinMode