I'm trying to set up a system where an android app connects to Arduino via Bluetooth and tells it to either turn on or off its LED. I've looked through a lot of pages and source code and saw many people did it as I did but somehow my code isn't working and I cannot determine why.
Here's the entirety of my Arduino code, really simple and short.
#include <SoftwareSerial.h>
SoftwareSerial Blue(0,1); // rx tx
int LED = 13; // Led connected
char data;
char state = 0;
void setup()
{
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
Serial.begin(9600);
Blue.begin(9600);
}
void loop()
{
while(Blue.available()==0);
if(Blue.available()>0){ // read from android via bluetooth
data = Blue.read();
Serial.println(data);
}
if (data == '1') // If data is 1, turn ON the LED
{
digitalWrite(LED,HIGH);
Serial.println("LED ON ");
}
if( data == '2') // if data is 2, turn OFF the LED
{
digitalWrite(LED,LOW);
Serial.println("LED OFF");
}
}
And here's a snippet of my android code that sends data to Arduino to control LED
switchLight.setOnClickListener(new View.OnClickListener() { // button that will switch LED on and off
#Override
public void onClick(View v) {
Log.i("[BLUETOOTH]", "Attempting to send data");
if (mmSocket.isConnected() && btt != null) { //if we have connection to the bluetoothmodule
if (!lightflag) {
try{
mmSocket.getOutputStream().write("1".toString().getBytes());
showToast("on");
}catch (IOException e) {
showToast("Error");
// TODO Auto-generated catch block
e.printStackTrace();
}
//btt.write(sendtxt.getBytes());
lightflag = true;
} else {
try{
mmSocket.getOutputStream().write("2".toString().getBytes());
showToast("off");
}catch (IOException e) {
showToast("Error");
// TODO Auto-generated catch block
e.printStackTrace();
}
//btt.write(sendtxt.getBytes());
lightflag = false;
}
}
else {
Toast.makeText(MainActivity.this, "Something went wrong", Toast.LENGTH_LONG).show();
}
}
});
This is the part of the code that connects to Arduino Bluetooth module. Again, fairly simple stuff and its only purpose are to connect to the module.
BluetoothAdapter bta; //bluetooth stuff
BluetoothSocket mmSocket; //bluetooth stuff
BluetoothDevice mmDevice; //bluetooth stuff
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("[BLUETOOTH]", "Creating listeners");
final TextView response = findViewById(R.id.response);
Button switchLight = findViewById(R.id.switchlight);
Button connectBT = findViewById(R.id.connectBT);
connectBT.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BluetoothSocket tmp = null;
mmDevice = bta.getRemoteDevice(MODULE_MAC);
Log.i("[BLUETOOTH]", "Attempting to send data");
try {
tmp = mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
mmSocket = tmp;
mmSocket.connect();
Log.i("[BLUETOOTH]","Connected to: "+mmDevice.getName());
showToast("Connected to: " + mmDevice.getName());
}catch(IOException e){
try {mmSocket.close();
}catch(IOException c){return;}
}
}
});
When I connect my android to the Arduino and track the serial monitor on Arduino IDE, instead of reading either 1 or 2, it reads something that looks like this:
This is produced using the Serial. println function in my Arduino code and I'm pretty sure it should display 1 or 2 but as you can see it does not. I've tried multiple workarounds like declaring it as int or char etc. If you can pinpoint any issue I'd much appreciate it.
Related
I have a piece of code that do not work, and I cannot understand why. As the subject says, it logs in to Twitter, but redirects back to the sign in button. setupTimeline(); is never executed.
I am using twitter4j library, it is at the latest version, 4.0.7.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the preferences for the app.
tweetzPrefs = getSharedPreferences("TweetzPrefs", 0);
// Find out if the user preferences are set.
if (tweetzPrefs.getString("user_token", null) == null) {
// No user preferences so prompt to sign in.
setContentView(R.layout.activity_main);
// Get a twitter instance for authentication.
tweetzTwitter = new TwitterFactory().getInstance();
// Pass developer key and secret.
tweetzTwitter.setOAuthConsumer(TWIT_KEY, TWIT_SECRET);
// Try to get request token.
try {
new Thread(new Runnable() {
#Override
public void run() {
try {
// Get authentication request token.
tweetzRequestToken = tweetzTwitter.getOAuthRequestToken(TWIT_URL);
Log.e(LOG_TAG, "Are we there Yeti?");
} catch (TwitterException e) {
e.printStackTrace();
Log.e(LOG_TAG, "TwitterException: " + e.getMessage());
}
if (tweetzRequestToken == null) {
Log.e(LOG_TAG, "tweetzRequestToken == null.");
}
}
}).start();
// Get authentication request token.
// tweetzRequestToken = tweetzTwitter.getOAuthRequestToken(TWIT_URL);
} catch (Exception e) {
e.printStackTrace();
Log.e(LOG_TAG, "Exception: " + e.getMessage());
}
// Setup button for click listener.
Button signIn = (Button) findViewById(R.id.signin);
signIn.setOnClickListener(this);
} else {
// User preferences are set, get timeline.
setupTimeline();
}
}
Any ideas anyone?
Regards.
When i click send button it is not sending any messages
The program gives no error, please help me solve this.
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setBody(edtContent.getText().toString());
chatMessage.setSenderId(QBChatService.getInstance().getUser().getId());
chatMessage.setSaveToHistory(true);
try {
qbChatDialog.sendMessage(chatMessage);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
QBChatMessagesHolder.getInstance().putMessage(qbChatDialog.getDialogId(), chatMessage);
ArrayList<QBChatMessage> messages = QBChatMessagesHolder.getInstance().getChatMessagesByDialogId(qbChatDialog.getDialogId());
adapter = new ChatMessageAdapter(getBaseContext(), messages);
lstChatMessages.setAdapter(adapter);
adapter.notifyDataSetChanged();
I used the quick blox sdk in my app. below is the code for sending message and its working fine.
private void sendChatMessage(String text) {
QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setBody(text);
chatMessage.setProperty(PROPERTY_SAVE_TO_HISTORY, "1");
chatMessage.setDateSent(System.currentTimeMillis() / 1000);
try {
if (Network.isNetworkConnected(ChatActivity.this)) {
chatDialog.sendMessage(chatMessage);
showMessage(chatMessage);
messageEditText.setText("");
checkIfOpponentIsOnline(chatMessage.getBody());
} else {
ToastUtil.showShortToast(ChatActivity.this, "Please check Internet connection and Try again");
}
} catch (SmackException e) {
Log.e(TAG, "Failed to send a message", e);
ToastUtil.showShortToast(ChatActivity.this, R.string.chat_send_message_error);
} catch (Exception e) {
Log.e(TAG, "Failed to send a message", e);
}
}
If you are still having trouble then you must check the dialogId and dialogUsers on your Quickblox console . There must be something wrong.Check for existence of users in dialog. Also check for ChatService Session cause if there is no session you won't be able to send any messages.
I have barcode scanner who should work with my app. It is supposed to run in the background and my app is responding to input coming from the scanner in its own way. However it should not be used as a hardware keyboard and its input not directed to the firstresponder (no text entries i.e.). Currently i'm stuck with it although i know i have done a solution like described before (couple years ago for a company).
The first part of the question is now how to prevent the bluetooth device from being attached as a hardware keyboard? Can i control this behaviour or is it maybe some mode or setting that the bluetooth device must support (if yes is there name for it to check in the specifications)?
I guess if the device is not attached as a bluetooth keyboard i could establish a connection and listen to the bluetooth socket input stream for available bytes and collect them. Currently i cannot establish a connection because
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
socket = device.createRfcommSocketToServiceRecord(uuid);
socket.connect();
throws an java.io.IOException with message read failed, socket might closed or timeout, read ret: -1. Any ideas why i cannot connect to the socket, although the device is currently paired to my device?
EDIT:
Because it was asked, the complete connection source code
private void initBluetooth() {
BTAdapter = BluetoothAdapter.getDefaultAdapter();
if (BTAdapter == null) {
Log.e(getClass().getName(), "no BT Adapter");
return;
}
if (!BTAdapter.isEnabled()) {
Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBT, REQUEST_BLUETOOTH);
return;
}
listDevices();
}
private void listDevices() {
Set<BluetoothDevice> pairedDevices = BTAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
Log.d(getClass().getName(), String.format("Device found %s", device.getName()));
if(device.getName().indexOf("Barcode") > 0) {
mmDevice = device;
try {
openBT();
} catch(IOException e) {
Log.e(getClass().getName(), "Failed", e);
}
break;
}
}
}
}
void openBT() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
//now make the socket connection in separate thread
Thread connectionThread = new Thread(new Runnable() {
#Override
public void run() {
// Always cancel discovery because it will slow down a connection
BTAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
//connection to device failed so close the socket
e.printStackTrace();
try {
mmSocket.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
});
connectionThread.start();
mmInputStream = mmSocket.getInputStream();
}
I have tried to play many audio (mp3) files through MediaPlayer's setAudioStreamType(AudioManager.STREAM_VOICE_CALL); but mp.start(); does not play nor does it throw an exception.
The setup works with SoundPool but it is limited to like 5 seconds, some files playing upto 8 seconds.
I am attaching the part of code here:
String s = absolutepath.get(position);
Uri u = Uri.parse(s);
playing = (MediaPlayer) MediaPlayer.create(MainActivity.this, u);
playing.setOnPreparedListener(this);
onPrepared includes this:
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
spProgress.cancel();
mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
try {
mp.start();
} catch (IllegalStateException e) {
Toast.makeText(this, "exception", Toast.LENGTH_SHORT).show();
}
}
I have tried this without the try/catch and even without listener. The only time it plays is when I don't use the stream type STREAM_VOICE_CALL.
The same files can be played with SoundPool:
SoundPool sp = new SoundPool(1, AudioManager.STREAM_VOICE_CALL, 0);
sp.load(s, 1);
sp.setOnLoadCompleteListener(this);
Listener:
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// TODO Auto-generated method stub
if (status == 0) {
spProgress.cancel();
sp.play(sampleId, 1, 1, 1, 0, 1);
} else {
Toast.makeText(this, "failed to load", Toast.LENGTH_SHORT).show();
}
}
I actually had the same problem, and Google's Guide is very bad here - it's indeed a bit tricky, but simple to explain:
As you need to change the STREAM, and then prepare() your MediaPlayer again, you'll get it working by doing this:
Resources res = getResources();
AssetFileDescriptor afd = res.openRawResourceFd(R.raw.tts_a);
mp = new MediaPlayer();
//mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
mp.setLooping(false);
try {
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mp.start();
The actual trick is to NOT use the MediaPlayer.create, as it's calling the prepare itself! Therefore you're not able to set the Stream. By setting the File with AssetFileDescriptor, you can set the Stream and call your prepare() afterwards!
I've been trying to create a function in my app that consist in a bluetooth RFID scanner, it's paired to my device and I have it working and all.
I can receive the text and log it in the console, when I compile the activity, everything goes fine, the stick reads the code, and then appends the text into an EditText, but if I go back and enter the activity again, I can see the code in the log, but the text doesn't go to the Edittext.
I tried a lot of different approaches, but nothing seems to work :/
here's the code I have:
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> bondedSet = mBluetoothAdapter.getBondedDevices();
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available.", Toast.LENGTH_LONG).show();
}
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this, "Please enable your BT and re-run this program.", Toast.LENGTH_LONG).show();
finish();
}
if (mBluetoothAdapter.isEnabled()) {
if(bondedSet.size() == 1){
for(BluetoothDevice device : bondedSet){
address = device.getAddress();
Log.d("bt:", address);
}
}
}
String address = "00:A0:96:2A:0A:1B";
out = (EditText) findViewById(R.id.output);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.d(TAG, device.getName() + " connected");
myConnection = new ConnectThread(device);
myConnection.start();
}
private class ConnectThread extends Thread {
private final BluetoothSocket mySocket;
Message msg;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.d(TAG, "CONNECTION IN THREAD DIDNT WORK");
}
mySocket = tmp;
}
Handler uiThreadHandler = new Handler() {
public void handleMessage(Message msg) {
out = (EditText) findViewById(R.id.output);
Object o = msg.obj;
out.append(o.toString().trim());
Log.d("handler", o.toString());
}
};
public void run() {
out = (EditText) findViewById(R.id.output);
Log.d(TAG, "STARTING TO CONNECT THE SOCKET");
setName("My Connection Thread");
InputStream inStream = null;
boolean run = false;
mBluetoothAdapter.cancelDiscovery();
try {
mySocket.connect();
run = true;
} catch (IOException e) {
Log.d(TAG, this.getName() + ": CONN DIDNT WORK, Try closing socket");
try {
mySocket.close();
Log.d(TAG, this.getName() + ": CLOSED SOCKET");
} catch (IOException e1) {
Log.d(TAG, this.getName() + ": COULD CLOSE SOCKET", e1);
this.destroy();
}
run = false;
}
synchronized (BluetoothActivity.this) {
myConnection = null;
}
byte[] buffer = new byte[1024];
int bytes;
// handle Connection
try {
inStream = mySocket.getInputStream();
while (run) {
try {
bytes = inStream.read(buffer);
readMessage = new String(buffer, 0, bytes);
msg = uiThreadHandler.obtainMessage();
msg.obj = readMessage;
uiThreadHandler.sendMessage(msg);
Log.d(TAG, "Received: " + readMessage);
} catch (IOException e3) {
Log.d(TAG, "disconnected");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
My guess is that this has something to do with the Thread itself. When you start your Activity for the first time, you also call .start() on the Thread, that would work fine.
The problem is when you leave your Activity and open it up again. In that case, one of onStop() or onPause() is called (depending on situation), and onRestart() or onResume() will be called afterwards respectively.
The trick comes now: Meanwhile all that process, your Thread is still running. As you show your code, it has not been stopped/paused, and keeps running all the time. So basically my tip is that there's something you do within your onCreate() method of your Activity that should also be done in your onPause() and onStop() events, and my another tip it's somewhere within your ConnectThread(BluetoothDevice device) method.
To know how to procceed, I'd firstly define both onStop() and onPause() methods within your Activity and see which is fired, log every attribute to see its value/state, and that way you'll be able to debug what is failing.
There's a diagram of the Activity lifecycle.
Problem was solved, the code works, and the TextView get the inputstream, the problem was when i left the activity, the thread continued to work, so far, no problem at all, after TONS of hours spent on this, i turn the TextView a static var and it worked :)
If anyone reads this, i hope it helps.