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.
Related
I want to create a system that can send messages between android app with arduino using bluetooth module. I Used bluetooth terminal (android) made by qwerty
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
String Data = "";
void setup()
{
mySerial.begin(9600);
}
void loop() // run over and over
{
while(mySerial.available()==0)
{}
char character;
while(mySerial.available()>0)
{
character = mySerial.read();
mySerial.write(character);
}
data = data + character;
if (character == 13) {
mySerial.print("Received: ");
mySerial.println(data);
data = "";
}
}
Everything it's ok when I send single character, but if I send string data (more than 1 character) arduino can't received it correctly. always error data in second character received.
Anyone can describe and help me to solve the problem?
Any response are appreciated.
If solved the problem, I will posted the guide.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
String Data = "";
void setup() {
mySerial.begin(9600);
}
void loop() // run over and over
{
while(mySerial.available()==0)
{}
char character;
while(mySerial.available()>0)
{
character = mySerial.read();
mySerial.write(character);
data = data + character;
}
// data = data + character;
if (character == 13) {
mySerial.print("Received: ");
mySerial.println(data);
data = "";`enter code here`
}
}
If you are trying to get more than one character, use arrays to store all the characters from the buffer at once.
May be this will give you some idea.
this post does it nicely
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.
The exact problem I am having is the same as in this thread:
Why does the serial BT data I received get chopped out?
So I know I need to make delimiters and parse, which I what I need, but sadly the answer to that thread wasn't specific enough.
I need to send analog data (from 0-1023) in the Arduino over to the Android device, so I added a "n" as a delimiter to the end of each string before sending over as such:
#include <SoftwareSerial.h>
int bluetoothTx = 2;
int bluetoothRx = 3;
boolean toggle = true;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup()
{
//Setup usb serial connection to computer
Serial.begin(9600);
//Setup Bluetooth serial connection to android
bluetooth.begin(115200);
bluetooth.print("$$$");
delay(100);
bluetooth.println("U,57600,N");
bluetooth.begin(57600);
}
void loop()
{
//Read from serial to bluetooth
while(1) //to reduce jitters
{
String sensorString = String(analogRead(A0), DEC);
sensorString = sensorString + "n";
bluetooth.println(sensorString);
delay(100);
}
}
This is for the Arduino side.
For the Android side, I used the BluetoothChat example, so in the mHandler and in the switch-case of MESSAGE_READ, the codes are as such:
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(readMessage);
Where mConversationArrayAdapter is a String ArrayAdapter. May i know how I can modify the code within the MESSAGE_READ case so as to solve this problem?
Send a string of ascii characters formed by each nibble of 0-1023 code (2 bytes), and append it by newline character (i.e. /n). As an example if hex code to send is 0x03FF (i.e. 1023 decimal), then string to send will be 0x30,0x33,0x46,0x46,0x0A.
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.
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.