Hi, I am trying to create an analog signal from the Arduino that I control in realtime over Bluetooth from a PC.
To create the analog signal from the Arduino, I am simply using Timer1.pwm(9,X) where X is a byte (that's all the resolution I need).
The HC-05 Bluetooth is controlled by SoftwareSerial on pins 2 & 3 and is set to baud = 115200
If I try to send the signal at a frequency higher than about 100Hz (a datapoint every 10ms), the Arduino can't seem to cope. The values that I am sending end up in a buffer and the signal continues to be generated by the Arduino for some time after I cease transmitting it.
However the baud rate seems to be high enough to deal with it?
If anyone has any advice on where to look for bottlenecks, I would appreciate it.
#include <TimerOne.h>
#include <SoftwareSerial.h>
const byte period = 32; // for 8 bit DAC
SoftwareSerial BTserial(2, 3); // RX | TX
char c = ' ';
void setup()
{
pinMode(9, OUTPUT);
Timer1.initialize(period);
BTserial.begin(115200);
}
void loop()
{
if (BTserial.available())
{
c = BTserial.read();
Timer1.pwm(9, c);
}
}
Since you are not using the hardware serial port for the bluetooth device, that means that it is available for debugging your program Perhaps you should use that capability...
Since there doesn't seem much that can go wrong with the Arduino end, I'm forced to assume that the problem is on the sending end.
Thanks - I am using matlab to send the signal and as far as I can tell, it is sending each data point at almost exactly the right time. The problem appears to be at the Arduino end.
How quickly SHOULD the Arduino be able to receive and process each data point? I know that if I generate the signal "on-chip" it can output it fine. It seems that it can't read the data points quick enough over bluetooth though. I have also changed the PC COM port that the bluetooth is on to 115200 so I am a bit stumped
byte count=0;
if (BTSerial.available()){
Serial.print(BTSerial.read())
count++;
}
if (count>20){ // Just to format it a bit....
Serial.println("");
count=0;
}
Thanks for the advice. I ran the code suggested and can confirm that the correct data is being received. I also changed the USB comms to Serial.begin(115200); to check if that was the bottleneck.
If I try to send 10 seconds of data at a rate quicker than 1 point per 5ms, it seems to end up in the buffer for a few seconds (i.e. Matlab finishes sending data at exactly 10 seconds while the Arduino is receiving for 12 seconds). If I send it at 1 point per 6ms, they finish at about the same time.
Ideally I would like to be able to transfer the data quicker than that - am I expecting too much?
At the matlab end, I am using fwrite(BT, x, 'uint8') i.e sending each number in as a single byte. If I read it as a byte on the Arduino end, I get exactly the same number.
To debug things a little further, I also used Serial.print(millis());
It seems that I can't get data into the Arduino any quicker than about 5ms. And the delays between datapoints can be up to 10-20ms at the Arduino end.
The delays in receiving a new data point appear to be regular...
If I transmit a byte every 10ms, most of the bytes are received approximately every 10ms, however there is a large delay every 200ms (~20 bytes / datapoints) of around 25ms (see graph attached)
If I transmit a byte every 4ms, there is a large delay every ~10 bytes (40ms), again of approx 20-25ms. (see graph attached)
If I transmit a byte every 5ms, there is a large delay every ~8 bytes (40ms), again of approx 20-25ms.
If I transmit a byte every 6ms, there is a large delay every ~33 bytes (200ms), again of approx 20-25ms.
If I transmit a byte every 20ms, there is general jitter around 15-25ms with large delays again every ~10 bytes (200ms),
If I transmit 512 bytes all at once from Matlab, I can get it across in ~1 second. However, the delays still occur, again approximately every 40ms, and they again last for 20-25ms.
So I can only assume that something is happening on the Arduino side every 40ms / 200ms that is screwing up my bluetooth receiving.
I thought these sorts of delays were to be expected with a software serial?
I thought the norm was to use the software serial for a bit of debugging but when you wanted things to go fast, you moved the Bluetooth to the hardware serial.
You could try switching the Bluetooth to the hardware serial and use a USB to TTL with the software serial. Maybe giving the Bluetooth the hardware serial will speed things up.
I suggest debugging on the software serial in moderation.