Arduino: using Serial and Software Serial with bluetooth module - android
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.
Related
HC-06 Bluetooth to Android - Receiving Random Symbols
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).
Send String + Int data through Bluetooth Arduino
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.
Arduino Mega ADK strange acc.write() behavior (huge delay) NAK issue seemd to be confirmed. Android generates NAK's as a result of acc.write
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.
control a servo with android and arduino
I'm trying to control a servo with an android phone and an arduino via bluetooth but the data in the arduino is received as a char, and the arduino doesn't know when all the data is received and the servo don't move properly. The arduino code is this: #include Servo myservo; char val; // variable to receive data from the serial port int ledpin = 13; // LED connected to pin 48 (on-board LED) void setup() { pinMode(ledpin, OUTPUT); // pin 48 (on-board LED) as OUTPUT Serial.begin(9600); // start serial communication at 9600bps myservo.attach(9); } void loop() { if( Serial.available() ) // if data is available to read { val = Serial.read(); // read it and store it in 'val' } if( val - 0 >= 0 && val - 0 <= 180){ } // Serial.print("Recibido"); delay(100); // wait 100ms for next reading } What can I do to get the correct value from "val" to control the servo?
You can send multiple chars if you need them. Simple store each new char into an array and program your android program to send a specific byte that indicates the ending of the val reading. Checking this "ending" byte each time you perform a read from serial will tell you if this char is to store or to convert the previous stored chars into an integer or whatever data type you need it. Than simply converting that array will tell you the correct val.
Bluetooth serial communication issue between Arduino and Android
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.