I'm trying to create some connected device which would stay local. But I would like to create an app which when I'm connected to my home WiFi could control this device.
To control the device I'm using an Node MCU so I can connect to the WiFi with my ESP8266 module, I will call it ESP from now on. For now I'm just trying to blink the integrated LED on the card to test it and it works when I do some HTTP request through Chrome App. I'm using ESP8266WebServer library to receive and respond HTTP requests.
My idea was that it would be easy to just make an app with a button sending an HTTP request to the local IP of my ESP (192.168.1.57), so I downloaded Android Studio and made an app with a button triggering a request. To do so I'm using Volley library which seems perfect for what I'm trying and the app works when requesting https://www.google.com .
My problem is that it can make a request but not to my ESP server ( http://192.168.1.57 ).
I saw that some people advised to set the ESP IP on a port of the box so I can go through internet to reach my ESP but I would like to stay local.
Here are the codes of :
Node MCU V3 (ESP 8266)
#include <Arduino.h>
#include <Servo.h>
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
/* VARIABLES */
/* Server */
char name[] = "FlowerPot";
char password[] = "xxxxxxxx";
int port = 80;
ESP8266WebServer server(port);
int request = 0;
/* Output */
int led1 = LED_BUILTIN; // Led de la carte , Pin D4, est allumé pour 0 et éteinte pour 1
int servo_pin = 2; // Variable pin PWM servo, ici Pin D4
Servo servo1; // Variable servo
/* FUNCTIONS DECLARATION */
void handleRoot();
void handleLED();
void handleNotFound();
/* CODE */
void setup() {
/* Server setup */
Serial.begin(9600);
WiFiManager wifiManager;
//se connecte au WIFI
if (!wifiManager.autoConnect(name,password)) {
Serial.println("failed to connect and hit timeout");
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(1000);
}
Serial.println("Connected!");
//demarre le serveur
server.on("/", handleRoot); // Call the 'handleRoot' function when a client requests URI "/"
server.on("/LED", handleLED); // Call the 'handleLED' function quand on appelle l'URL avec "/LED"
//server.on("/LED", HTTP_POST, handleLED); // Call the 'handleLED' function when a POST request is made to URI "/LED"
server.onNotFound(handleNotFound); // When a client requests an unknown URI (i.e. something other than "/"), call function "handleNotFound"
server.begin(); // Actually start the server
Serial.println("HTTP server started");
/* Blink setup */
pinMode(led1,OUTPUT);
/* Servo setup *//*
servo1.attach(servo_pin); */
}
void loop() {
/* Server */
server.handleClient(); // Listen for HTTP requests from clients
/* Blink */
if(request){
digitalWrite(led1,0);
delay(1000);
digitalWrite(led1,1);
delay(4000);
}
/* Servo controle *//*
servo1.write(10);
delay(1000);
servo1.write(90);
delay(1000);
servo1.write(170);
delay(1000); */
}
void handleRoot() {
//server.send(200, "text/html", "<form action=\"/LED\" method=\"POST\"><input type=\"submit\" value=\"Toggle LED\"></form>");
server.send(200, "text/html", "Root");
digitalWrite(led1,!digitalRead(led1));
}
void handleLED() { // If a POST request is made to URI /LED
digitalWrite(led1,!digitalRead(led1)); // Change the state of the LED
/* server.sendHeader("Location","/"); // Add a header to respond with a new location for the browser to go to the home page again
server.send(303); // Send it back to the browser with an HTTP status 303 (See Other) to redirect */
server.send(200, "text/html", "LED");
}
void handleNotFound(){
server.send(404, "text/plain", "404: Not found"); // Send HTTP status 404 (Not Found) when there's no handler for the URI in the request
}
Android App Main Activity
package com.example.flowerpotapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendMessage(View view){
Button myButton = (Button)findViewById(R.id.button);
final TextView myTextView = (TextView)findViewById(R.id.errors);
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://192.168.1.57";
//String url ="https://www.google.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
myTextView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
myTextView.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
if(myButton.getText() == "OFF"){
myButton.setText("ON");
} else {
myButton.setText("OFF");
}
}
}
Some precision I test it with my phone a OnePlus 7 on android 10 and connected on the same WiFi as my ESP with my phone.
Related
I want to read html code of arduino web server.
I can make web server simply with from example 4. code is below.
#include <SoftwareSerial.h>
#include "WiFly.h"
#define SSID "yum2"
#define KEY "yum000000"
// check your access point's security mode, mine was WPA20-PSK
// if yours is different you'll need to change the AUTH constant, see the file WiFly.h for avalable security codes
#define AUTH WIFLY_AUTH_WPA2_PSK
int flag = 0;
// Pins' connection
// Arduino WiFly
// 2 <----> TX
// 3 <----> RX
SoftwareSerial wiflyUart(2, 3); // create a WiFi shield serial object
WiFly wifly(&wiflyUart); // pass the wifi siheld serial object to the WiFly class
void setup()
{
wiflyUart.begin(9600); // start wifi shield uart port
Serial.begin(9600); // start the arduino serial port
Serial.println("--------- WIFLY Webserver --------");
// wait for initilization of wifly
delay(1000);
wifly.reset(); // reset the shield
delay(1000);
//set WiFly params
wifly.sendCommand("set ip local 80\r"); // set the local comm port to 80
delay(100);
wifly.sendCommand("set comm remote 0\r"); // do not send a default string when a connection opens
delay(100);
wifly.sendCommand("set comm open *OPEN*\r"); // set the string that the wifi shield will output when a connection is opened
delay(100);
Serial.println("Join " SSID );
if (wifly.join(SSID, KEY, AUTH)) {
Serial.println("OK");
} else {
Serial.println("Failed");
}
delay(5000);
wifly.sendCommand("get ip\r");
char c;
while (wifly.receive((uint8_t *)&c, 1, 300) > 0) { // print the response from the get ip command
Serial.print((char)c);
}
Serial.println("Web server ready");
}
void loop()
{
if(wifly.available())
{ // the wifi shield has data available
if(wiflyUart.find("*OPEN*")) // see if the data available is from an open connection by looking for the *OPEN* string
{
Serial.println("New Browser Request!");
delay(1000); // delay enough time for the browser to complete sending its HTTP request string
// send HTTP header
wiflyUart.println("HTTP/1.1 200 OK");
wiflyUart.println("Content-Type: text/html; charset=UTF-8");
wiflyUart.println("Content-Length: 244"); // length of HTML code
wiflyUart.println("Connection: close");
wiflyUart.println();
// send webpage's HTML code
wiflyUart.print("<html>");
wiflyUart.print("<head>");
wiflyUart.print("<title>My WiFI Shield Webpage</title>");
wiflyUart.print("</head>");
wiflyUart.print("<body>");
wiflyUart.print("<h1>Hello World!</h1>");
wiflyUart.print("<h3>10 20 30 40 50</h3>");
wiflyUart.print("Yahoo! Google");
wiflyUart.print("<br/><button>My Button</button>");
wiflyUart.print("</body>");
wiflyUart.print("</html>");
}
}
}
the web server work well.
I wrote simple android code to read html is below.
package com.example.http;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private TextView tv;
String urlAddress = "192.168.0.10"; // doesn't show
// String urlAddress = "http://www.kma.go.kr/weather/main.jsp#1159068000"; // work well
Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.textView1);
Button b = (Button)findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadHtml();
}
});
}
void loadHtml() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
final StringBuffer sb = new StringBuffer();
try {
URL url = new URL(urlAddress);
HttpURLConnection conn =
(HttpURLConnection) url.openConnection();
if (conn != null) {
conn.setConnectTimeout(2000);
conn.setUseCaches(false);
if (conn.getResponseCode()
== HttpURLConnection.HTTP_OK) {
BufferedReader br
= new BufferedReader(new InputStreamReader
(conn.getInputStream()));
while (true) {
String line = br.readLine();
if (line == null) break;
sb.append(line + "\n");
}
br.close();
}
conn.disconnect();
}
Log.d("test", sb.toString());
handler.post(new Runnable() {
#Override
public void run() {
tv.setText(sb.toString());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.start();
}
}
It work very well with String urlAddress = "http://www.kma.go.kr/weather/main.jsp#1159068000";
but it doesn't show when using
String urlAddress = "192.168.0.10"; instead of before one.
the 192.168.0.10 is allocated ip of arduino from DHCP that i can check on serial monitor.
there is any way to read html from arduino web server??
Your urlAddress isn't a URL, it's just an IP address. You should fully qualify the address with the protocol and the path you want to land on, for example:
String urlAddress = "http://192.168.0.10/";
I would expect you're getting a MalformedURLException.
I'm trying to communicate with an ESP8266 WiFi chip from an Android device using WebSockets to remotely control some motors connected to an Arduino. First I prototyped using a PC & Python & set up a WebSocket server on the ESP8266...
ESP8266_server.ino
#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>
const char* ssid = "SKYNET";
const char* password = "yourdogsauntsmaidenname";
WebSocketsServer webSocket = WebSocketsServer(81);
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {
//Serial.printf("[%u] get Message: %s\r\n", num, payload);
switch(type) {
case WStype_DISCONNECTED:
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
// Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
}
break;
case WStype_TEXT:
{
//Serial.printf("[%u] get Text: %s\r\n", num, payload);
String _payload = String((char *) &payload[0]);
Serial.print(_payload);
}
break;
case WStype_BIN:
{
hexdump(payload, lenght);
}
// echo data back to browser
webSocket.sendBIN(num, payload, lenght);
break;
}
}
void setup() {
// Set up serial comms
Serial.begin(115200);
// Set up WiFi
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
// Serial.print(".");
delay(200);
}
// Serial.println("");
// Serial.println("WiFi connected");
// Serial.println("IP address: ");
// Serial.println(WiFi.localIP());
delay(500);
// Set up web socket
// Serial.println("Start Websocket Server");
webSocket.begin();
webSocket.onEvent(webSocketEvent);
}
void loop() {
webSocket.loop();
}
The WiFi chip is connecetd via a serial connection to an Arduino Mega which in turn parses the data to control some H-bridges for 2 DC motors. The Arduino also relays the data to the Arduino IDE serial monitor.
motor_control.ino
// Serial comms from Wemos EPS8622 to Arduino Mega
#include "SoftPWM.h"
// Outputs to PWM & H bridge direction
// PWMs:
// DC_pwm, left_pwm, right_pwm = 3, 4, 5
int pwm_out[] = {3, 4, 5};
const int num_pwm = sizeof(pwm_out) / sizeof(pwm_out[0]);
// H bridge direction control:
// right_2, right_1, left_2, left_1, dc_2, dc_1 = 6, 7, 8, 9, 10 ,11
int dir_pins[] = {6, 7, 8, 9, 10 , 11};
const int num_dir_pins = sizeof(dir_pins) / sizeof(dir_pins[0]);
// Input buffer from ESP8266
int in_buff[] = {0, 0};
const int num_in_buff = sizeof(in_buff) / sizeof(in_buff[0]);
void setup() {
// Set up serial comms
Serial.begin(115200); // Debug to Serial Monitor
Serial3.begin(115200); // From ESP8266
// Set up PWM pins
SoftPWMBegin();
for (int i = 0; i < num_pwm; i++)
{
SoftPWMSet(pwm_out[i], 0);
}
// Set up H bridge direction pins
for (int i = 0; i < num_dir_pins; i++)
{
pinMode(dir_pins[i], OUTPUT);
digitalWrite(dir_pins[i], LOW);
}
}
void loop() {
// Check input from EPS8266 & send it to the H bridges
while (Serial3.available() < num_in_buff){}
if (Serial3.available()) {
// read the incoming bytes
// in_buff[0] - direction flags
// in_buff[1] - PWM
Serial.println(".......");
Serial.println("In from ESP8266");
for (int i = 0; i < num_in_buff; i++){
in_buff[i] = Serial3.read();
Serial.println(in_buff[i]);
}
Serial.println(".......");
}
// Set direcions on H bridges
Serial.println("Direction pins");
for (int i = 0; i < num_dir_pins; i++)
{
digitalWrite(dir_pins[i], bitRead(in_buff[0], i));
Serial.print("pin ");
Serial.print(dir_pins[i]);
Serial.print(" : ");
Serial.print(digitalRead(dir_pins[i]));
Serial.println();
}
// PWM to motors
for (int i = 0; i < num_pwm; i++)
{
SoftPWMSet(pwm_out[i], in_buff[1]);
}
}
On the PC side I have some Python code that is set up as a WebSocket client that takes user input from the terminal & transmits to the ESP chip.
motor_control_WiFi.py
"""
Motor control over WiFi using Wemos EPS8266 & Mega board
Motor H-bridge direction flags
Both forwards - b'111001, d'57, ASCII 9
Both backwards - b'110110, d'54, ASCII 6
Clockwise (right) - b'111010, d'58, ASCII :
A/Clock (left) - b'110101, d'53, ASCII 5
"""
from ws4py.client.threadedclient import WebSocketClient
import time, requests
import struct
esp8266host = "ws://192.168.1.84:81/"
class DummyClient(WebSocketClient):
def opened(self):
print("Websocket open")
def closed(self, code, reason=None):
print("Connexion closed down", code, reason)
def received_message(self, m):
print(m)
if __name__ == '__main__':
try:
ws = DummyClient(esp8266host)
ws.connect()
print("Ready !")
direction = ""
while direction != "q":
direction = input("Direction: ")
if direction == "f":
payload = "9"
if direction == "b":
payload = "6"
if direction == "r":
payload = ":"
if direction == "l":
payload = "5"
ws.send(payload)
time.sleep(.20)
pwm_out = int(input("PWM: "))
pwm_out = struct.pack('<B', pwm_out)
ws.send(pwm_out)
time.sleep(.20)
print("Finished, close Websocket connexion now and exit script")
ws.send("0:0")
ws.close()
exit()
except KeyboardInterrupt:
ws.send("0:0")
ws.close()
This all works fine. So my next step was to make an Android app to do what my Python code is doing. I'm using the okhttp3 library & added implementation 'com.squareup.okhttp3:okhttp:3.6.0' to the Gradle build file & added internet permissions to the manifest.
MainActivity.java
package qdivision.org.websocketexample;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
public class MainActivity extends AppCompatActivity {
private Button start;
private TextView output;
private OkHttpClient client;
private final class EchoWebSocketListener extends WebSocketListener {
private static final int NORMAL_CLOSURE_STATUS = 1000;
#Override
public void onOpen(WebSocket webSocket, Response response) {
//webSocket.send("l");
webSocket.send(ByteString.decodeHex("23"));
webSocket.send(ByteString.decodeHex("32"));
webSocket.close(NORMAL_CLOSURE_STATUS, "Goodbye !");
}
#Override
public void onMessage(WebSocket webSocket, String text) {
output("Receiving : " + text);
}
#Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
output("Receiving bytes : " + bytes.hex());
}
#Override
public void onClosing(WebSocket webSocket, int code, String reason) {
webSocket.close(NORMAL_CLOSURE_STATUS, null);
output("Closing : " + code + " / " + reason);
}
#Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
output("Error : " + t.getMessage());
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.start);
output = (TextView) findViewById(R.id.output);
client = new OkHttpClient();
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
start();
}
});
}
private void start() {
Request request = new Request.Builder().url("ws://192.168.1.84:81").build(); //"ws://echo.websocket.org"
EchoWebSocketListener listener = new EchoWebSocketListener();
WebSocket ws = client.newWebSocket(request, listener);
client.dispatcher().executorService().shutdown();
}
private void output(final String txt) {
runOnUiThread(new Runnable() {
#Override
public void run() {
output.setText(output.getText().toString() + "\n\n" + txt);
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="qdivision.org.websocketexample.MainActivity">
<Button
android:id="#+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Start !"
android:layout_marginTop="40dp"
android:textSize="17sp"/>
<TextView
android:id="#+id/output"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/start"
android:layout_centerHorizontal="true"
android:textSize="16sp"
android:layout_marginTop="30dp"/>
</RelativeLayout>
When this is deployed I dont get any connection errors. The sent bytes are echoed back to the display & the client disconnects with no error. BUT I get no feed back via the Arduino Serial Monitor that anything has been sent!
What's missing here? How come no connection error if the bytes are not being sent/recieved?
Edit #1 I ran the Python code on the Android device from the Termux command line. The code runs, says the socket is open & lets me input direction & PWM but still nothing from the serial monitor.
Edit #2 I can ping the ESP8266 from the Android device using Termux with 0 package loss but still no data being sent by either the Python code or the app.
Edit #3 Python code now works from the Termux command line on the Android device (no idea how I made no changes, it just works now??!!??). The okhttp3 based app still sends no data.
I’m pretty new to Arduino and Processing and and this is also my first time asking a question about coding on the internet.
I’m currently trying to do the following thing for a school project: I want to send a String with data from sensors on my Arduino to a android phone or tablet over bluetooth.
For simplicity’s sake I reduced the code in complexity, removing every part of my code that isn’t trying to facilitate the transfer of a String from Arduino to Processing on Android. The following code is simply trying to send the String “S01E” to the processing app on my phone, saving the String into my “String info” and displaying that string in form of a text(info, 20, 110); element.
Additional Info:
Arduino bluetooth module is a “Bluefruit EZ-Ling BLuetooth Shield”.
Phone is Samsung Galaxy S8.
Processing App is generated with Android mode of Processing.
My phone is successfully paired with the arduino over bluetooth.
The code compiles successfully, but it only shows my text(“test text”, 20, 120); on my phone, but not my text(info, 20, 110);, which I assume means that the String is not being received and the info String stays empty.
How can i proceed from here? Are there some obvious problems in my code. And how can I properly debug my code with the weird stack of technologies that I use?
Processing Code:
import netP5.*;
import android.content.Intent;
import android.os.Bundle;
import ketai.net.bluetooth.*;
import ketai.ui.*;
import ketai.net.*;
KetaiBluetooth bt;
boolean isConfiguring = true;
String info = "";
KetaiList klist;
ArrayList devicesDiscovered = new ArrayList();
// States of the two sensors
int B1in = 0;
int B2in = 0;
//********************************************************************
// The following code is required to enable bluetooth at startup.
//********************************************************************
void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bt = new KetaiBluetooth(this);
}
void onActivityResult(int requestCode, int resultCode, Intent data) {
bt.onActivityResult(requestCode, resultCode, data);
}
void setup() {
size(displayWidth, displayHeight);
frameRate(10);
orientation(PORTRAIT);
background(255);
stroke(160);
fill(50);
//start listening for BT connections
bt.start();
//at app start select device…
isConfiguring = true;
}
void draw() {
background(255);
text(info,20,110);
text("test text",20,120);
println(info);
}
void onKetaiListSelection(KetaiList klist)
{
String selection = klist.getSelection();
bt.connectToDeviceByName(selection);
//dispose of list for now
klist = null;
}
//Call back method to manage data received
void onBluetoothDataEvent(String who, byte[] data) {
if (isConfiguring)
return;
//received
info = new String(data);
}
And here is my Arduino code:
#include <SoftwareSerial.h>
SoftwareSerial bt(2,3); // RX, TX
// Enthält den String, der an den PC geschickt wird
String data = "S01E";
// Serielle Schnittstelle einrichten, pinModes setzen
void setup() {
bt.begin(9600);
Serial.begin(9600);
}
void loop() {
Serial.println(data);
}
I also asked the same Question on discourse.processing.org. The link to my Question:
https://discourse.processing.org/t/sending-string-from-arduino-to-processing-app-on-android-over-bluetooth/6106
Could you try this?
void setup() {
isConfiguring = true;
size(displayWidth, displayHeight);
frameRate(10);
orientation(PORTRAIT);
background(255);
stroke(160);
fill(50);
//start listening for BT connections
bt.start();
//at app start select device…
isConfiguring = false;
}
It seems the function your using to retrieve data from the Bluetooth event is simply returning because of your Boolean flag is never changing from true.
I am uploading the code of both the android-studio as well as the arduino uno.. It seems right but somehow it doesn't work
Android Studio code :
package com.example.chintan.doorlock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import android.os.Handler;
public class MainActivity extends AppCompatActivity {
private final String DEVICE_ADDRESS = "00:21:13:01:ED:10"; //MAC Address of Bluetooth Module
private final UUID PORT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
private BluetoothDevice device;
private BluetoothSocket socket;
private OutputStream outputStream;
private InputStream inputStream;
Thread thread;
byte buffer[];
boolean stopThread;
boolean connected = false;
String command;
Button lock_state_btn, bluetooth_connect_btn;
TextView lock_state_text;
ImageView lock_state_img;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lock_state_btn = (Button) findViewById(R.id.lock_state_btn);
bluetooth_connect_btn = (Button) findViewById(R.id.bluetooth_connect_btn);
lock_state_text = (TextView) findViewById(R.id.lock_state_text);
lock_state_img = (ImageView) findViewById(R.id.lock_state_img);
bluetooth_connect_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
if(BTinit()) //initialises bluetooth
{
BTconnect(); //connects android code to arduino
beginListenForData();
// The code below sends the number 3 to the Arduino asking it to send the current state of the door lock so the lock state icon can be updated accordingly
command = "3";
try
{
outputStream.write(command.getBytes());
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
});
lock_state_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
if(connected == false)
{
Toast.makeText(getApplicationContext(), "Please establish a connection with the bluetooth servo door lock first", Toast.LENGTH_SHORT).show();
}
else
{
command = "1";
try
{
outputStream.write(command.getBytes()); // Sends the number 1 to the Arduino. For a detailed look at how the resulting command is handled, please see the Arduino Source Code
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
});
}
void beginListenForData() // begins listening for any incoming data from the Arduino
{
final Handler handler = new Handler();
stopThread = false;
buffer = new byte[1024];
Thread thread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopThread)
{
try
{
int byteCount = inputStream.available();
if(byteCount > 0)
{
byte[] rawBytes = new byte[byteCount];
inputStream.read(rawBytes);
final String string = new String(rawBytes, "UTF-8");
handler.post(new Runnable()
{
public void run()
{
if(string.equals("3"))
{
lock_state_text.setText("Lock State: LOCKED"); // Changes the lock state text
lock_state_img.setImageResource(R.drawable.locked_icon); //Changes the lock state icon
}
else if(string.equals("4"))
{
lock_state_text.setText("Lock State: UNLOCKED");
lock_state_img.setImageResource(R.drawable.unlocked_icon);
}
}
});
}
}
catch (IOException ex)
{
stopThread = true;
}
}
}
});
thread.start();
}
#Override
protected void onStart()
{
super.onStart();
}
}
And this is my arduino source code :
//Android-controlled Arduino Bluetooth Servo Door Lock by uscv
#include <Servo.h>
#include <EEPROM.h>
Servo servo;
char state;
void setup() {
// put your setup code here, to run once:
servo.attach(7);
if(EEPROM.read(0) == 1) // Reads the EEPROM value stored to know what state the door lock was in before it was last turned off
{ // An EEPROM value of 1 means UNLOCKED and a value of 2 means LOCKED
servo.write(0); // Rotates the servo to the unlocked position
delay(200);
}
else if(EEPROM.read(0) == 2)
{
servo.write(75); // Rotates the servo to the locked position
delay(200);
}
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available() > 0)
{
char data;
data = Serial.read(); // The variable data is used to store the value sent by the Android app
switch(data)
{
case '1':
if(EEPROM.read(0) == 1) //An EEPROM value of 1 means it is currently unlocked
{
EEPROM.write(0, 2); // Writes the number 2 to address 0 on the Arduino's EEPROM. This value will be used by the Arduino to remember the last state the door lock was in
Serial.print("3"); // Sends the number 3 to the Android app. To see what this does, please see the Android Studio Project file
servo.write(75);
delay(15);
}
else if(EEPROM.read(0) == 2) //An EEPROM value of 2 means it i currently locked
{
EEPROM.write(0, 1); // Writes the number 1 to address 0 on the Arduino's EEPROM. This value will be used by the Arduino to remember the last state the door lock was in
Serial.print("4"); // Sends the number 4 to the Android app. The number sent will be used by the app to update the locked/unlocked icon
servo.write(0);
delay(15);
}
break;
case '3':
if(EEPROM.read(0) == '1')
{
Serial.print("4");
}
else if(EEPROM.read(0) == '2')
{
Serial.print("3");
}
break;
}
}
}
So, first the android app will start bluetooth, then connect to the arduino uno card and then perform the following functions:
1. "3" sent from android phone to arduino
2. received either "4" or "3" based on its status from arduino uno to android
3. Change the lock image on the android phone
4. send "1" from the android phone to the arduino
5. Change the status of the servo motor sg90 from its current position
Now, my android application is error-free and connects to the arduino uno and also is able to start the bluetooth of the phone. It establishes the connection but does not change the position of the servo motor sg90. I dont understand the problem what should we do?
You are calling EEPROM.read() before initializating the EEPROM. In other words for example in your setup() you are checking whether you EEPROM address 0 contains a certain value rather than initialization it with a certain value. Then
in your loop(), again you are checking whether EEPROM address contains a certain value before any value is written to the EEPROM and thus you will never reach the EEPROM write part because your if statements always returns false. So, start first by writing a value to EEPROM address 0.
I am new to android, i want to download the files from FTPs server, On emulater i am able to download files but when i try on target board it is giving error at ftp.auth(SSLFTPClient.AUTH_TLS);
Below is the my code, please suggest me where i am wrong.
package com.android.ftp;
import java.io.File;
import android.app.Activity;
import android.os.Bundle;
import com.enterprisedt.net.ftp.FTPClientInterface;
import com.enterprisedt.net.ftp.FTPConnectMode;
import com.enterprisedt.net.ftp.FTPTransferType;
import com.enterprisedt.net.ftp.ssl.SSLFTPClient;
import com.enterprisedt.util.debug.Level;
import com.enterprisedt.util.debug.Logger;
public class Ftp_testActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String host = "ftp.xyz.com";
String username = "abcd";
String password = "pqr";
String filename = "/mnt/sdcard/video1/747.3gp";
// set up logger so that we get some output
Logger log = Logger.getLogger(Ftp_testActivity.class);
Logger.setLevel(Level.INFO);
SSLFTPClient ftp = null;
try {
// create client
log.info("Creating FTPS (explicit) client");
ftp = new SSLFTPClient();
// disable standard SSL closure
log.info("Setting configuration flags");
ftp.setConfigFlags(SSLFTPClient.ConfigFlags.DISABLE_SSL_CLOSURE);
// set remote host
log.info("Setting remote host");
ftp.setRemoteHost(host);
ftp.setRemotePort(21);
// turn off server validation
log.info("Turning off server validation");
ftp.setValidateServer(false);
// connect to the server
log.info("Connecting to server " + host);
ftp.connect();
// switch to SSL on control channel
log.info("Switching to FTPS (explicit mode)");
ftp.auth(SSLFTPClient.AUTH_TLS);
// log in
log.info("Logging in with username=" + username + " and password="
+ password);
ftp.login(username, password);
log.info("Logged in");
ftp.setConnectMode(FTPConnectMode.PASV);
ftp.setType(FTPTransferType.ASCII);
putGetDelete(filename, ftp);
log.info("Successfully transferred in ASCII mode");
// Shut down client
log.info("Quitting client");
ftp.quit();
log.info("Example complete");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void putGetDelete(String name, FTPClientInterface ftp)
throws Exception {
ftp.put(name, name);
ftp.get(name + ".copy", name);
ftp.delete(name);
File file = new File(name + ".copy");
file.delete();
}
}
You should try:
ftp.setRemotePort(990);
where 990 is port SSL default.