My scenario is the following:
I have a few buttons connected to an Arduino Nano, which is connected to my PC over Serial. Now I want to send a few bytes whenever a button is pressed, to be interpreted by my Computer. However, I noticed a significant, unregular delay (feels like something between almost instantaneous transmission up to a delay of easily ~300 milliseconds), until the message is received by my computer, and I want to get rid of that.
I understand that Arduinos make use of a Serial Buffer, and only send over data once the buffer is full (or some sort of timeout probably), and I think that is the culprit - however I don't see a way of forcing the Arduino to send the data ASAP. I tried just sending over exactly 64 bytes (which, according to what I read, should be the buffer size), but that doesn't help as well (can I however decrease the buffer size or is there a way to send bytes exactly until the buffer is full?)
I don't think baudrate changes anything either, as I'm experiencing problems with the "ping" rather than with the bandwidth (and I also tried anything from 9600 to 115200).
Maybe I'm also completely wrong and the delay happens on the side of my computer, but I don't know if there is anything to change that - I'm looking at the Serial Monitor or at a small pyserial
script, both of which have the delay:
arduino = serial.Serial(serial_port}, 115200, timeout=.1)
while True:
data = arduino.readline().decode("UTF-8").strip()
if data:
print(data)
The code on the Arduino-side boils down to:
#include <digitalWriteFast.h>
#define button1_pin 2
int button1_state = 0;
int last_button1_state = 0;
void setup() {
Serial.begin(115200);
pinMode(button1_pin, INPUT_PULLUP);
while (!Serial) { delay(50); }
Serial.println("Started");
}
void loop() {
button1_state = digitalReadFast(button1_pin);
if (button1_state != last_button1_state) {
if (button1_state == LOW) {
Serial.write("d\n");
} else {
Serial.write("u\n");
}
last_button1_state = button1_state;
delay(20);
}
}
Then there's also the weirdest thing which I noticed but am not sure about if it's at all plausible: When the window of the Serial Monitor (the one that ships with the Arduino IDE) is not completely full (meaning there are only some 1-20 rows and the window doesn't need to scroll), I notice the aforementioned delay, but if the Serial Monitor is full (so new content will be on the last line and the window automatically scrolls a bit), I don't. As soon as I clear the output of the window, it's there again. I don't know what to make of this observation, because I definitely don't have any reasonable clue why that may be the case, so maybe it's also just my imagination :shrug:. Using the python-code there is no such behaviour, and the transimission always seems to have a ping of at least 200-300ms.
I hope my problem is understandable, and like I said I am really unsure what even is the culprit (and I see that it's also highly likely that it's on the side of my computer), but does anybody have any idea how I can decrease this delay? Thanks a lot!
Serial.write()
or its siblings) the transmission begins in the background (orchestrated through interrupts). The baudrate also defines how long the transmission of a byte needs, so it also correlates to the "ping" in a way. Have you tried changing the timeout value in the python code? At the moment you have 0.1 (I guess this is seconds). Does this change anything in the outcome?readline()
waits until it returns, and neither increasing nor decreasing changes something. Note however that I see the same issues in the Arduino IDE's Serial Monitor, so I don't think this problem is on the side ofpyserial
.