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?
The HC-06 acts as a serial port through which you can send and receive data. By using a serial terminal or a Bluetooth customized application on your computer or phone, you can control and monitor your project.
Tap the HC06 in the list, and you will then be asked for the PIN - it is 1234. Finally, open your terminal app on the smartphone, and select "Connect a device" from the app menu. Select the HC-06 option and then wait a moment. The LED on the Bluetooth module should stay on and the app will show "connected: HC-06" .
Every message the Arduino wants to send, is first given to the Bluetooth-Module, which sends the message wirelessly. To avoid problems with the UART, Arduino and Bluetooth-Module have to use the same baud-rate (in default 9600).
The HC-06 Bluetooth module is permanently configured to be slave and is always in AT mode when not paired to any other device. Open Arduino IDE and go to Tools, then Serial Monitor. Set the Baud rate to 9600 and the 'line ending' to 'Both NL and CR'. Type in 'AT' without the quotes and click send.
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:
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);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With