Bluetooth read/write

Hello,

I am working on a project that involves sending data from my Arduino to an android app I am writing.

I have the hardware set-up complete, and am able to read my HC-05 on my android.

Here comes the tricky part, trying to send data across has got me a little flustered. I have never done this before, and after 12hrs of trying to read tutorials and watch youtube, I feel further behind then ahead.

Arduino Code:

#include <LiquidCrystal.h>
#include "HX711.h"

char data = 0;            //Variable for storing received data

HX711 scale(3, 2);
LiquidCrystal lcd(12, 11, 8, 7, 6, 5);  

float calibration_factor = -9040;

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);  // initializes the 16x2 LCD
  scale.set_scale();
  scale.tare(); //Reset the scale to 0

  long zero_factor = scale.read_average(); //Get a baseline reading
}

void loop() {
  float weight;
  lcd.setCursor(0,0);           
  lcd.print(" This is a Scale!");               
  
  scale.set_scale(calibration_factor); //Adjust to this calibration factor
  weight = scale.get_units(5);
  if(weight < 0.1){
    weight=0.0;
  }
  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1);
  
  Serial.print(" lbs");
  Serial.println();
  delay(500);
  lcd.setCursor(2,1);           //sets the cursor at row 1 column 2
  lcd.print(weight);            // prints the weight
  lcd.print(" LBS    ");
  
  if(Serial.available() > 0)      // Send data only when you receive data
   {
      data = Serial.read();        //Read the incoming data & store into data
      Serial.print(data);          //Print Value inside data in Serial monitor
      Serial.print("\n");        
      if(data == '1'){             // Checks whether value of data is equal to 1
        // recieve request for weight from android?
      }
      else if(data == '0'){        //  Checks whether value of data is equal to 0
        // send wieght to android?
      }    
   }
}

Android Code:

package d.trying;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;

import android.bluetooth.BluetoothAdapter;

import java.text.DateFormat;
import java.util.Date;
import java.util.Set;

public class MainActivity extends AppCompatActivity {
    private double weight = 200.2;
    private int i=0;
    private BluetoothAdapter btAdapter;
    private boolean btconnected = false;
    private ArrayAdapter<String> pairedDevicesArray;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button bluetooth = (Button)findViewById(R.id.BlueTooth);
        bluetooth.setOnClickListener(new View.OnClickListener() {

            public void onClick(View y) {
                TextView bluetooth = (TextView) findViewById(R.id.bluetooth);
                BluetoothAdapter btAdapter =  BluetoothAdapter.getDefaultAdapter();
                if(btAdapter==null) {
                    bluetooth.setText("No BlueTooth! :(");
                    btconnected = false;
                }
                else if(!btAdapter.isEnabled()){
                    bluetooth.setText("BlueTooth found, not enabled! :(");
                    btconnected = false;
                }
                else {
                    Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
                    btconnected = true;
                    //if(pairedDevices.toString() == "[98:D3:31:FC:3A:F5]"){
                    //    bluetooth.setText("Found the Scale!");
                    //}
                    bluetooth.setText(pairedDevices.toString());
                }
            }
        });

        Button addweight = (Button)findViewById(R.id.addweight);
        addweight.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if(btconnected) {
                    onWeightClick(v);
                }
            }
        });

        Button clear = (Button)findViewById(R.id.Clear);
        clear.setOnClickListener(new View.OnClickListener(){

            public void onClick(View x){
                SharedPreferences sp = getSharedPreferences("key", Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();
                editor.clear();
                editor.commit();
                TextView clear = (TextView) findViewById(R.id.weightText);
                clear.setText("");
                weight=200.2;
            }
        });
    }

    public void onWeightClick(View v) {
        String dateTime = DateFormat.getDateTimeInstance().format(new Date());
        TextView display = (TextView) findViewById(R.id.weightText);
        String weightString = "";
        SharedPreferences sp = getSharedPreferences("key", Context.MODE_PRIVATE);

        weightString = sp.getString("key", new String());

        weightString += "\n" + dateTime + "  :   " + weight + " lbs";

        display.setText(weightString);
        weight++;

        SharedPreferences.Editor editor = sp.edit();
        editor.putString("key", weightString);
        editor.commit();
    }
}
  long zero_factor = scale.read_average(); //Get a baseline reading
}

and store it in a local variable that immediately goes out of scope, resulting in nothing but having wasted time. Why would you want to do THAT?

void loop() {
  float weight;
  lcd.setCursor(0,0);           
  lcd.print(" This is a Scale!");

Do you REALLY need to print that on every pass through loop()?

  scale.set_scale(calibration_factor); //Adjust to this calibration factor

Do you need to do THAT on every pass through loop()?

What are you using Serial to talk to? The PC or the bluetooth device/android?

Both is the wrong answer. So is yes.

Well thanks for the help PaulS, you definitly answered my questions.

For now I am trying to turn on the LED on pin 13, with a button push on my android.

The android App is crashing when I push the bluetooth button, I commented out much of the code in an attempt to error-check.

Android code:

package d.trying;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;

import android.bluetooth.BluetoothAdapter;

import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.util.Date;
import java.util.Set;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private double weight = 200.2;
    private int i=0;
    private BluetoothAdapter btAdapter;
    private boolean btconnected = false;
    private ArrayAdapter<String> pairedDevicesArray;
    private String DEVICE_ADDRESS;
    private BluetoothSocket btSocket = null;
    private OutputStream outStream = null;
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button bluetooth = (Button)findViewById(R.id.BlueTooth);
        bluetooth.setOnClickListener(new View.OnClickListener() {

            public void onClick(View y) {

                TextView bluetooth = (TextView) findViewById(R.id.bluetooth);
                BluetoothAdapter btAdapter =  BluetoothAdapter.getDefaultAdapter();
                if(btAdapter==null) {
                    bluetooth.setText("No BlueTooth! :(");
                    btconnected = false;
                }
                else if(!btAdapter.isEnabled()){
                    bluetooth.setText("BlueTooth found, not enabled! :(");
                    btconnected = false;
                }
                else {
                    Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
                    btconnected = true;
                    bluetooth.setText(pairedDevices.toString());
                    if(bluetooth.getText().toString().equals("[98:D3:31:FC:3A:F5]")){
                        DEVICE_ADDRESS = bluetooth.getText().toString();
                        bluetooth.setText("Found the Scale!");

                        // Set up a pointer to the remote device using its address.
                     //   BluetoothDevice device = btAdapter.getRemoteDevice(DEVICE_ADDRESS);
                        // Create a bluetooth socket for comms
                      /*  try{
                            btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
                        } catch(IOException e){
                            bluetooth.setText("Could not create Bluetooth socket");
                        }
                 */   }
                }

                //sendData("1");
            /*
                try {
                    btSocket.connect();
                } catch (IOException e) {
                    try{
                        btSocket.close();
                    } catch(IOException e2){
                        bluetooth.setText("Could not close Bluetooth socket");
                    }
                }
                try{
                    outStream = btSocket.getOutputStream();
                } catch (IOException e){
                    bluetooth.setText("Could not create bluetooth outstream");
                }
            */
               // sendData("1");
            }
        });

        Button addweight = (Button)findViewById(R.id.addweight);
        addweight.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if(btconnected) {
                    onWeightClick(v);
                }
            }
        });

        Button clear = (Button)findViewById(R.id.Clear);
        clear.setOnClickListener(new View.OnClickListener(){

            public void onClick(View x){
                SharedPreferences sp = getSharedPreferences("key", Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();
                editor.clear();
                editor.commit();
                TextView clear = (TextView) findViewById(R.id.weightText);
                clear.setText("");
                weight=200.2;
                sendData("0");
            }
        });
    }

    public void onWeightClick(View v) {
        String dateTime = DateFormat.getDateTimeInstance().format(new Date());
        TextView display = (TextView) findViewById(R.id.weightText);
        String weightString = "";
        SharedPreferences sp = getSharedPreferences("key", Context.MODE_PRIVATE);

        weightString = sp.getString("key", new String());

        weightString += "\n" + dateTime + "  :   " + weight + " lbs";

        display.setText(weightString);
        weight++;

        SharedPreferences.Editor editor = sp.edit();
        editor.putString("key", weightString);
        editor.commit();
    }
    public void sendData(String message) {
        byte[] msgBuffer = message.getBytes();

        //attempt to place data on the outstream to the BT device
        try {
            outStream.write(msgBuffer);
        } catch (IOException e) {
            //if the sending fails this is most likely because device is no longer there
            //bluetooth.setText("Device not found");
            finish();
        }
    }
}

Revised Arduino Code:

#include <LiquidCrystal.h>
#include "HX711.h"

HX711 scale(3, 2);
LiquidCrystal lcd(12, 11, 8, 7, 6, 5);  

float calibration_factor = -9040;
char data = 0;            //Variable for storing received data

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);  // initializes the 16x2 LCD
  scale.set_scale();
  scale.tare(); //Reset the scale to 0

  pinMode(13, OUTPUT);
}

void loop() {
  float weight;
  
  scale.set_scale(calibration_factor); //Adjust to this calibration factor
  weight = scale.get_units(5);
  
  if(weight < 0.1){
    weight=0.0;
    lcd.noDisplay();
  }
  else if(weight > 0.1){
    lcd.display();
    lcd.setCursor(0,0);           
    lcd.print("This is a Scale!!");  
    lcd.setCursor(2,1);           // Sets the cursor at row 1 column 2
    lcd.print(weight);            // prints the weight
    lcd.print(" LBS    ");
  }
  
  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1);
  
  Serial.print(" lbs");
  Serial.println();
  delay(500);
  
  if(Serial.available() > 0){      // Send data only when you receive data:
      delay(100);
      data = Serial.read();        // Read the incoming data & store into data
      Serial.print(data);          // Print Value inside data in Serial monitor
      Serial.print("\n");        
      if(data == '1'){             // Checks whether value of data is equal to 1
        digitalWrite(13, HIGH);    // If value is 1 then LED turns ON
      }
      else if(data == '0'){        // Checks whether value of data is equal to 0
        digitalWrite(13, LOW);     // If value is 0 then LED turns OFF
      }
      else if(data == '*'){
        lcd.setCursor(0,0);           
        lcd.print("PHONE FOUND!!");         
      }
   } 
}
        Button bluetooth = (Button)findViewById(R.id.BlueTooth);
        bluetooth.setOnClickListener(new View.OnClickListener() {

            public void onClick(View y) {

                TextView bluetooth = (TextView) findViewById(R.id.bluetooth);

I find it hard to follow this code. Why do you have two different things named bluetooth, with different types? You call findViewById() with the same value, but you expect to get a Button object and a TextView object. That doesn't make sense, to me.

This better? btStatus is just a textview, and btbutton, well a button.

Button bluetooth = (Button)findViewById(R.id.btButton);
        bluetooth.setOnClickListener(new View.OnClickListener() {

            public void onClick(View y) {

                TextView btStatus = (TextView) findViewById(R.id.btStatus);
                BluetoothAdapter btAdapter =  BluetoothAdapter.getDefaultAdapter();

The problem I am having is not there… it is with this line, crashing the program if I hit btButton.
If I comment it out, it works.
As I mentioned, this is my first time trying something like this, and if I am following the tutorials I found correctly, it should work, but clearly something is wrong.
Please don’t bitch about my variable names, or coding style, I am an amateur, clearly, I am posting here to get help to solve this issue, if someone knows what is going wrong.
I did not post here to have someone complain that the code is not pretty.

BluetoothDevice device = btAdapter.getRemoteDevice(DEVICE_ADDRESS);

DEVICE_ADDRESS is:

DEVICE_ADDRESS = btStatus.getText().toString();

the bt.Status text view:

TextView btStatus = (TextView) findViewById(R.id.btStatus);
btStatus.setText(pairedDevices.toString());
public class MainActivity extends AppCompatActivity {
    private double weight = 200.2;
    private int i=0;
    private BluetoothAdapter btAdapter;
    private boolean btConnected = false;
    private ArrayAdapter<String> pairedDevicesArray;
    private String DEVICE_ADDRESS;
    private BluetoothSocket btSocket = null;
    private OutputStream outStream = null;
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button bluetooth = (Button)findViewById(R.id.btButton);
        bluetooth.setOnClickListener(new View.OnClickListener() {

            public void onClick(View y) {

                TextView btStatus = (TextView) findViewById(R.id.btStatus);
                BluetoothAdapter btAdapter =  BluetoothAdapter.getDefaultAdapter();
                if(btAdapter==null) {
                    btStatus.setText("No BlueTooth! :(");
                    btConnected = false;
                }
                else if(!btAdapter.isEnabled()){
                    btStatus.setText("BlueTooth found, not enabled! :(");
                    btConnected = false;
                }
                else {
                    Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
                    btConnected = true;
                    btStatus.setText(pairedDevices.toString());
                    if(btStatus.getText().toString().equals("[98:D3:31:FC:3A:F5]")){
                        DEVICE_ADDRESS = btStatus.getText().toString();
                        btStatus.setText("Found the Scale!");

                        // Set up a pointer to the remote device using its address.
                        BluetoothDevice device = btAdapter.getRemoteDevice(DEVICE_ADDRESS);
                        // Create a bluetooth socket for comms
                      /*  try{
                            btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
                        } catch(IOException e){
                            btStatus.setText("Could not create Bluetooth socket");
                        }
                 */   }
                }

This better?

Yes.

The problem I am having is not there.... it is with this line

Which line is "this line"?

Please don't bitch about my variable names, or coding style

Who's bitching? The reason that I said anything was that it appeared that you were trying to use one object, found by findViewById() for two radically different purposes. That didn't pass the sniff test.

DEVICE_ADDRESS = btStatus.getText().toString();

Again, this does not pass the sniff test. btStatus LOOKS like the name of a widget where one would expect to find some status information, not a device address.

If you control the names, and the text field is where an address is actually entered, then a better name would certainly make the context clearer.

In C and C++, the convention is that all capital letter names are reserved for constants. Constants do not appear on the left of an equal sign except for when being declared and initialized. So, perhaps a different name would be better.

Do you solve your problem? If no, I suggest you to have a look at the bottom window in Android Studio, in which you will see a red block of text explaining the crash (when you click on the Bluetooth Btn). You can open it by clicking on the link "Android Monitor" at the bottom of the window.

Also, you can click just a few mm at the right of the line number in the editor, in from of a line of code. This will draw a red circle which is a "breakpoint". This mean that when your code will reach this point, it will stop and on the bottom part of the window, using the Debug link, you will see value of variable, content of array and hashmap and so on.
You can set as many breakpoint as you want and when you reach one, you can "run again" the App clicking on the arrow at left top of debug window.

Also, add a LOT of comment in your code. This will help you to understand what you're doing and will help people wanting to help you.

Regards
Feroce Lapin