I have written an application for Android in Java using Eclipse to send data to an Arduino via Bluetooth.
The devices seem to be connected okay, but when I send data from the Android to the Arduino the receive (RX) light on the Arduino board doesn't light up.
Can someone help?
#define arduinoRx 2
#define arduinoTx 3
int gelen_veri;
int LedCikis = 8;
SoftwareSerial bluetooth(arduinoRx, arduinoTx);
void setup() {
bluetooth.begin(9600);
}
void loop() {
if (bluetooth.available() > 0) {
gelen_veri=bluetooth.read();
switch (gelen_veri) {
case 'A' :
digitalWrite(LedCikis, HIGH);
break;
case 'K' :
digitalWrite(LedCikis, LOW);
break;
default:
break;
}
}
}
Use the serial rx/tx pins instead of SoftwareSerial. I've had problems with SoftwareSerial in the past and my HC-05 bluetooth module.
Related
I wanted to send values from a light sensor, using an HC-06. I have everything connected properly. I used MIT App Inventor and the image shows how I connect to the Bluetooth module, and how do I show the data.
Arduino Code
int analogInPin = A0;
int sensorValue = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
sensorValue = analogRead(analogInPin);
Serial.println(sensorValue);
delay(100);
}
Phone
I already searched for several solutions but none worked. I have the baud rate at 9600 (the same as the Bluetooth module).
I am new to Arduino and I have been working on a problem that has been troubling me for a few days.
I have an Arduino Uno and an HC-05 Bluetooth module.
Basically I want to send String and Int data together through Bluetooth.
CODE
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
void setup(void) {
// Arduino setup
Serial.begin(9600);
// setting the baud rate of bluetooth
BTSerial.begin(38400); // HC-05 default speed in AT command more
}
void loop(void) {
int num = 123;
BTSerial.write("#"); // Works
BTSerial.write(num); // works
BTSerial.write(String(num) + "#");
// Error: no matching function for call to 'SoftwareSerial::write(StringSumHelper&)'
}
Also the result string should have '#' character at last.
According to the Arduino Website, it has 2 functions.
- Serial.write(val)
- Serial.write(str)
Any help appreciated.
Thank you.
write is for sending raw bytes. You want to use Serial.print instead.
if you want to send String from an another device to arduino, your code sould be like this:
#include <SoftwareSerial.h>
SoftwareSerial BT(3, 4);
String bt = "";
void setup() {
BT.begin(9600);
Serial.begin(9600);
}
void loop() {
if(BT.available()){
bt = BT.readString();
}
Serial.println(bt);
while(!BT.available());
}
the above code, waits for your bluetooth module to recieve any data and reads a String from it and prints it in Serial.
In order to send Int, you can read a String and parse it to Int.
I am building an internet controlled robot that uses 2 android phones for controlling.
The first phone is connected to Arduino Uno via USB and serves as a 3G shield
The second phone is used to control the whole thing. It sends unassigned byte to the first phone which sends it to Arduino.
The apps I uses on the phones have one problem. The joystick in the app doesn't send a specific command when its in rest. For example when I move it up it sends "1" to the phone connected to the Arduino which drives the motors forward but when I release the joystick it stops sending data however the motors on my robot still spin until I move the joystick down which sends "2" motor.run(RELEASE);
How can I stop the motors if there is no Serial Data available?
This is the code i wrote.
#include <AFMotor.h>
AF_DCMotor motor_left(2, MOTOR12_1KHZ);
AF_DCMotor motor_right(3, MOTOR12_1KHZ);
int ledPin = 13;
int speed_min = 100; //the minimum "speed" the motors will turn - take it lower and motors don't turn
int speed_max = 1000; //the maximum "speed" the motors will turn – you can’t put in higher
int speed_left = speed_max; // set both motors to maximum speed
int speed_right = speed_max;
int command = 0;
void setup ()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
motor_left.setSpeed(255);
motor_left.run(RELEASE);
motor_right.setSpeed(255);
motor_right.run(RELEASE);
motor_left.setSpeed(speed_left); // minimum speed 135 max speed 255
motor_right.setSpeed(speed_right); // minimum speed 135 max speed 255
}
void loop() {
if (Serial.available() > 0);
byte command = Serial.read();
if (command == 1)
{
Serial.println("Move Forward");
digitalWrite(ledPin, HIGH);
motor_left.run(FORWARD);
}
if (command == 2)
{
Serial.println("Stop");
digitalWrite(ledPin, LOW);
motor_left.run(RELEASE);
}
}
So basically it should do nothing if there is no data available.
Use your code like this, it will help
void loop() {
if (Serial.available() > 0) {
byte command = Serial.read();
if (command == 1) {
Serial.println("Move Forward");
digitalWrite(ledPin, HIGH);
motor_left.run(FORWARD);
} else if (command == 2) {
Serial.println("Stop");
digitalWrite(ledPin, LOW);
motor_left.run(RELEASE);
} else {
//put your code to stop Motor
}
}
}
I'm trying to communicate between Arduino Mega Adk (ADK 2011) and android device.
Something goes ok, but something goes completely wrong.
Transfer data from Android to Arduino via acc.read from Arduino side works fine.
But when i try to send some bytes from Arduino to Android - something strange happens.
First of all here is Arduino sketch:
#include <Max3421e_constants.h>
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
#define COMMAND_LED 0x2
#define TARGET_PIN_18 0x12
#define TARGET_PIN_19 0x13
#define V_ON 0x1
#define V_OFF 0x0
#define PIN_18 18
#define PIN_19 19
#define INPUT_PIN 30
AndroidAccessory acc("Google, Inc.",
"DemoKit",
"Ololo device board",
"1.0",
"http://www.android.com",
"0000000012345678");
byte rcvmsg[3];
byte sndmsg[3];
int buttonState = 0;
void setup();
void loop();
void led_setup(){
pinMode(PIN_18, OUTPUT);
pinMode(PIN_19, OUTPUT);
pinMode(INPUT_PIN, INPUT);
}
void setup()
{
Serial.begin(115200);
Serial.print("\r\nStart");
led_setup();
acc.powerOn();
}
void loop()
{
if (acc.isConnected()) {
buttonState = digitalRead(INPUT_PIN);
if (buttonState == 1){
sndmsg[0] = 0x2;
sndmsg[1] = 0x1;
sndmsg[2] = 0x1;
int len = acc.write(sndmsg, 3);
digitalWrite(PIN_19, HIGH);
}
else {
//Nothing here for test
}
}
//usefull test for button
buttonState = digitalRead(INPUT_PIN);
if (buttonState == 1){
digitalWrite(PIN_19, HIGH);
}
else {
digitalWrite(PIN_19, LOW);
}
}
Ok. When acc.write() is executed it takes up to ~1 second to transfer data to android. And this time doesn't depend on number of bytes in sndmsg. Only if i execute acc.write(sndmsg,0) (sending 0 bytes) - everything goes fast.
That is a little bit disturbing. I've tried to change board to another one but have got the same result.
Any advices? may be that is a common bug, but there is no such much information in web.
UPD:
Wrote some very simple code, that only sends 3 bytes via acc.write.
here it is:
#include <Max3421e_constants.h>
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
AndroidAccessory acc("Google, Inc.",
"DemoKit",
"Demokit board",
"1.0",
"http://www.android.com",
"0000000012345678");
byte msg[3];
unsigned long time;
void setup();
void loop();
void led_setup(){
}
void setup()
{
Serial.begin(115200);
Serial.print("\r\nStart");
acc.powerOn();
}
void loop()
{
if (acc.isConnected()) {
Serial.print("\r\nis Connected");
msg[0] = 0x1;
msg[1] = 0x1;
msg[2] = 0x1;
//Serial.print("\r\nSending");
time = millis();
Serial.print ("\r\nBefore write\r\n");
Serial.print (time);
acc.write(msg, 3);
time = millis();
Serial.print("\r\nAfter write: \r\n");
Serial.print (time);
//delay(500);
}
}
And it's debug output is:
is Connected
Before write
6983
After write:
10958
is Connected
Before write
10958
After write:
14491
is Connected
and so on. So on some reasons acc.write takes a lot of time and there is no data in the android app.
New UPD (19.01.2015):
Today i've performed some experiments. Here are results.
First, i've looked into AndroidAccessory.cpp and found write function:
int AndroidAccessory::write(void *buff, int len)
{
usb.outTransfer(1, out, len, (char *)buff);
return len;
}
Ok, then i looked into usb host shield library and found there usb.cpp with outTransfer fucntion, that returns error code if ouccured and 0x00 if everything is ok.
So i modified write function to return an error code instead of lenght, like this:
int AndroidAccessory::write(void *buff, int len)
{
byte rcode;
rcode = usb.outTransfer(1, out, len, (char *)buff);
return int(rcode);
}
and recived "4" as result.
According to MAX3421Econstants.h it is hrNAK (0x04) error code.
Any ideas? Looks like accessory does not recive NAKs from Android and write fails as a result.
Situation update:
Did some research. There is a hell of NAK's when accessory is connected. Here is dump from usb connector:
i found the solution. And it is very simple - i didn't setup communication with accessory correctly.
This is not an Arduino problem. Arduino works fine.
It is just how android interacts with android accessory.
So, results:
When AndroidAccessory is plugged to Android and Android haven't setup
communication with the accessory yet, Android OS will send a lot of
USB NAKs to the accessory and this is normal.
You must be careful
during setuping communication with the accessory. If you make some
mistakes, you can receive same situation: Probably possible to write
to the accessory, but accessory isn't possible to write to the
android.
If UsbManager opens accessory correctly, it stops sending
NAKs and starts recieve data from arduino.
It is a little bit strange for me, because it was really hard to found a problem: i have an application, written according to this manual: http://developer.android.com/guide/topics/connectivity/usb/accessory.html But, because i'm not very familiar with android, it seems that i've done some mistakes and receive strange behavior:
i was able to write to arduino
i was able to retrive information about arduino as android accessory
it was possible to ask for permissions
but when arduino tries to write to android, it recievs a lot of NAKs
So i decided to rewrite program in more simple way, just with one function and tried to do it in right way. And after some debugging it finally started to work as i want.
So thank everyone, who spend time for reading this.
Bonus: dump of normal packet, ended with EOP not NAK
UPD 26.01.2015:
I found problem and it was in my android code.
here is explanation:
Android developer's manual said that function, which set up communication with accessory must start it's own thread in which all communications with input and output streams are held. Smth like this:
private void openAccessory() {
Log.d(TAG, "openAccessory: " + accessory);
mFileDescriptor = mUsbManager.openAccessory(mAccessory);
if (mFileDescriptor != null) {
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInputStream = new FileInputStream(fd);
mOutputStream = new FileOutputStream(fd);
Thread thread = new Thread(null, this, "AccessoryThread");
thread.start();
}
}
I really messed this thing up. Forgot about creating new thread in openAccessory function and tried to do it in different place. And recieve a hell of NAK's. Then i've changed my code and add some debug-like run() function like this:
public void run() {
final byte[] buffer = new byte[16384];
int ret = 0;
int i = 0;
while (i<50) {
try {
ret = mInputStream.read(buffer);
i++;
Thread.sleep(500);
} catch (IOException e) {
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
And until this run method exists (while i < 50) android reads arduino correctly. And when thread ends up (i > 50) - Arduino starts to readout Error Code 4 (NAK) from Android.
That's all folks.
My purpose is to use Arduino to set up communication between a PC and an Android device using an HC-05 bluetooth module.
I use the USB communication between the PC and the Arduino (Serial Monitor) and a SoftwareSerial to connect to the HC-05.
My problem is that the communication works well from BT to the PC, but doesn't work as expected in the other way. When sending from the PC to BT all the characters sent are received by the BT device only when I close the Serial Monitor on the PC or when I reset the Arduino.
I've excluded a problem with the BT Module or the Android application because if in Arduino I implement an "ECHO" code (write in Android and the send in Android) everything works fine.
With the Arduino code posted below the expected behaviour is: Arduino reset-> Hello word sent, Serial monitor opened-> nothing happens, character written on serial monitor-> character received on BT, character written on BT-> character received on Serial Monitor, Serial monitor closed-> nothing happens.
The real behaviour is: Arduino reset-> Hello word sent, Serial monitor opened-> 2 Hello word on BT and 1 ("goodnight") on PC, character written on serial monitor-> nothing, character written on BT-> character received on Serial Monitor, Serial monitor closed-> previous written character(s) in serial monitor received + Hello Word.
How can I fix this problem?
Code:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
int a=0;
char c;
char d;
void setup() {
Serial.begin(9600);
Serial.println("Goodnight moon!");
mySerial.begin(9600);
mySerial.println("Hello, world?");
}
void loop() {
delay(10);
if (Serial.available()) {
c=Serial.read();
delay(10);
Serial.write(c);
}
delay(10);
if (mySerial.available()) {
d=mySerial.read();
delay(10);
mySerial.write(d);
}
}
This code is working for me on an Arduino Mini Pro (should be the same as UNO) with an HC-05. I have the HC-05 paired with my laptop. Using HyperTerminal on the COM port associated with the HC-05 and the Arduino serial console, I can send messages bidirectionally. The Serial.println statements show up in the Hyperterminal window like they should.
#include <SoftwareSerial.h>
#define rxPin 8
#define txPin 7
SoftwareSerial mySerial(rxPin, txPin); // RX, TX
char myChar ;
void setup() {
Serial.begin(9600);
Serial.println("Goodnight moon!");
mySerial.begin(9600);
mySerial.println("Hello, world?");
}
void loop(){
while(mySerial.available()){
myChar = mySerial.read();
Serial.print(myChar);
}
while(Serial.available()){
myChar = Serial.read();
mySerial.print(myChar);
}
}
I have implemented a serial communication between Arduino Uno and PC and this was my code, hope it can help:
int data;
char character;
int start_flag = 0;
void setup() {
Serial.begin(921600);
pinMode(2, OUTPUT);
}
void loop() {
if(Serial.available() > 0){
character = (char) Serial.read();
if(character == 's') {
start_flag = 1;
}
if(character == 't') {
start_flag = 0;
}
}
if (start_flag == 1) {
Serial.print(data); //data that was acquired by internal ADC
}
}
You could try this. It's about the simplest code you can use when testing Arduino bluetooth <-> C# communication. Note: the code was tested by connecting PIN1(TX) <-> MODULE RX, PIN2(RX) <-> MODULE TX and dividing the PIN1(TX) 5V to 2,5V before feeding it to the module.
Hope this helps all that are trying this!
Use this serial setup. With this code I can receive and send date to bluetooth from Serial Monitor
void setup(){
Serial.begin(9600); // Begin the serial monitor at 9600bps
bluetooth.begin(115200); // The Bluetooth Mate defaults to 115200bps
bluetooth.print("$"); // Print three times individually
bluetooth.print("$");
bluetooth.print("$"); // Enter command mode
delay(100); // Short delay, wait for the Mate to send back CMD
bluetooth.println("U,9600,N"); // Temporarily Change the baudrate to 9600, no parity
// 115200 can be too fast at times for NewSoftSerial to relay the data reliably
bluetooth.begin(9600); // Start bluetooth serial at 9600
pinMode(led, OUTPUT);
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
}
For more information, visit
http://www.circuitmagic.com/arduino/arduino-and-bluetooth-hc-06-to-control-the-led-with-android-device/
I recommend to use this app for testing:
https://play.google.com/store/apps/details?id=com.vagoscorp.virtualterminal
It let you see and send bytes as bytes(number from 0b00000000 to 0b11111111 (0 to 255 in decimal))
so you can make a simple echo firmware to test if your baudrate is correct and with that working, begin sending commands to turn on/off some LEDs
this is an echo code example:
char dato = 0;
void setup() {
Serial.begin(9600);//9600 is the default baudrate of the HC-05 (you can change it by AT commands, google it if you want)
//pinMode(13, OUTPUT); //enable this pin if you want to use de LED idea
//digitalWrite(13, HIGH);
}
//////////////////////////////////////////////////////////////////////////
void serialEvent() { //if you have received serial data
while (Serial.available() > 0) {
char dato = (byte)Serial.read();//save the byte
Serial.write(dato);//send the just received byte (echo)
}
}
///////////////////////////////////////////////////////////////////////////
void loop() {
}
I hope it helps you
Had the same problem, you have to view the BT module as 2 different baud rates on the wired side and the radio side. The radio side is set by whatever you connect at through putty, the wired side is programmed via AT commands. HC-05 defaults at 38400.