I'm using Teensy 3.2 with a BlueSMiRF shield to send data to a Python script on a PC via bluetooth. When the data is transferred serially, it all appears perfectly in Python. However, when I try to send the data over bluetooth, the output will randomly jump to a new line. I wrote a script to output binary to see if it's some kind of error between the UART and RFCOMM protocols, but it seems that Python is receiving everything correctly- it just randomly jumps to a new line. Does anyone know what the issue might be?
I've attached by Arduino code below. It should send data in binary that's received from the Serial Monitor, and also print what binary it sent in the Serial Monitor. It only works for characters/strings, it just prints rubbish for numbers. My test message right now is "Hiya."
//#include <SoftwareSerial.h>
#define bluetooth Serial1
String myText = "a";
int baud = 115200;
byte myTextInBin = 0;
//
//int bluetoothRx = 0; // TX-O pin of bluetooth mate, Arduino D2
//int bluetoothTx = 1; // RX-I pin of bluetooth mate, Arduino D3
//
//SoftwareSerial bluetooth(bluetoothRx, bluetoothTx);
void setup()
{
// serial setup
Serial.begin(baud); // Begin the serial monitor at 9600bps
// bluetooth setup
bluetooth.begin(baud); // 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(baud); // Start bluetooth serial at 9600
Serial.println("Setup complete");
}
void loop()
{
if(bluetooth.available()) // If the bluetooth sent any characters
{
// Send any characters the bluetooth prints to the serial monitor
myText = bluetooth.readStringUntil('/');
Serial.println(myText);
// Serial.println((char)bluetooth.read());
}
if(Serial.available()) // If stuff was typed in the serial monitor
{
// Send any characters the Serial monitor prints to the bluetooth
myText = Serial.readStringUntil('/');
for(int i=0; i<myText.length(); i++){
char myChar = myText.charAt(i);
for(int i=7; i>=0; i--){
byte bytes = bitRead(myChar,i);
myTextInBin = (myTextInBin<<1) + bytes;
Serial.print(bytes, BIN);
}
Serial.println("");
bluetooth.print(myTextInBin);
}
//bluetooth.print (myTextInBin);
myTextInBin = 0;
}
// and loop forever and ever!
}
I've also attached my Python code for receiving the bluetooth data if anyone is familiar with that! I'm using the pybluez library, which is all I've been able to get to work on my computer.
"""
A simple Python script to connect with bluetooth adaptors
"""
import bluetooth
serverMACAddress = '00:06:66:FB:AD:2B'
client_socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
size = 1024
client_socket.connect((serverMACAddress, 1))
print("Left leg Connected ")
prompt_char = "^"
trial_start_char = "$"
trial_stop_char = "@"
client_socket.send("-99/")
print("Syncing")
while 1:
data_L = client_socket.recv(12000)
print(data_L)
client_socket.close()
Serial communication is very slow compared to how fast the processor is running. You may not be receiving the entire line all at the same time. Check out Robin2's tutotial on Serial communication basics which has some really good examples of how to do that reliably.
is complete worthless. You take a char and then convert it into the same number. What are you trying to do?
you could just as easily accomplish this by
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(baud); // Start bluetooth serial at 9600
You are not using any software serial, so why do you still need to do this?
byte bytes = bitRead(myChar,i);
The bitRead() macro returns a single bit, not something one would normally store in a plural variable.
It should send data in binary
Sending binary data is done using write(), not print(). Sending a string representing a value in binary is a different story.
It only works for characters/strings, it just prints rubbish for numbers.
I can't imagine what you are really trying to accomplish. I can't really visualize what you are sending to the Arduino, or what it is sending back. Some actual input and output would be useful.
@PaulS - sure, let me try to explain. I want to send a menu, then sensor data from the Teensy to the BlueSMiRF to be received by Python, and ultimately saved using lab streaming layer. When I tried to send the menu as strings, I first encountered this error (the data would randomly jump to new lines). I don't know much about bluetooth communication, so I suspected it might have something to do with the different communication protocols (Teensy sending data via UART, Python receiving via RFCOMM). After all, there's no problem sending the menu and sensor data serially over a wire at exactly the same baud rates. However, the data is being received in Python over bluetooth exactly as it is sent (no misunderstood/added/lost bits), it is just received in chunks/jumping to a new line.
To exemplify the issue, I'm sending a sample string from the serial monitor via Bluetooth into Python. When I send 'Hiya,' I get the 4 binary representations of those numbers printed in the serial monitor, each on their own line. I get varying results in Python. Sometimes b'Hiya', sometimes b'H', new line, then b'iya', sometimes b'Hi', new line, b'ya', etc. A new line randomly appears when I print data in Python, which I need to avoid. This is the error I cannot figure out.
I've corrected the .write issue- thanks for the help there! The software serial comment is from an older iteration. As for the bit function issues, I'm not surprised- this is completely new to me!
@blh64 - Do you know why sending data serially over a wire would work perfectly, but sending data serially over bluetooth would cause this error? Both wire and bluetooth communication were tested at exactly the same baud rates (115200).
I meant to write the binary to bluetooth, not print. This binary stuff is new to me.
Re-read this, and see if it makes sense to you. Data and lines are two complete separate concepts. YOU display data. How you display it is up to you. The python code you showed has no concept of lines, so I really have no idea what you are talking about.
However, the data is being received in Python over bluetooth exactly as it is sent (no misunderstood/added/lost bits), it is just received in chunks/jumping to a new line.
The data is NOT received in "chunks". It is sent, and received, one byte at a time. If you are adding a carriage return, or linefeed, or both, then you are causing the "jump to a new line".
I don't know how to make this any clearer:
SHOW YOUR INPUT AND OUTPUT.
Does this even compile? Nested for loops with the same name for the iterator... And even if it does compile, it's a terrible idea as it's very confusing which i you're referring to.
wvmarle:
Does this even compile? Nested for loops with the same name for the iterator... And even if it does compile, it's a terrible idea as it's very confusing which i you're referring to.
Of course it compiles. The for() creates an innter scope with only the inner 'i' visible.
I do agree that it is a terrible idea, but the compiler doesn't care...
I also figured out what my (newline) issue was. Fortunately it has less to do with my inability to code in Arduino and more to do with the .recv() method in Python.
The data is NOT received in "chunks". It is sent, and received, one byte at a time. If you are adding a carriage return, or linefeed, or both, then you are causing the "jump to a new line".
Fortunately for me, the data actually was being received in chunks of bytes, not in single bytes. Who would have thought? It seems that the .recv() doesn't care how the data is packaged from the bluetooth shield- it repackages the data into specified byte sizes. Is that the right way to say it? Probably not! But turns out this is a common issue for newbs like me. Note the link below: