I'm using Arduino for a project that requires low latency. Unfortunately, I noticed that even though incoming serial commands are fast, Arduino is executing commands really slowly.
I checked how much time does it take to send and receive data from Arduino. I got the time of around 2-3ms. That is OK, but the strange thing is that when I try to do some real work: turn off a led or move a stepper motor for example., it takes at least 8ms to execute that command. I know that because I have a fast camera in the same setup (it is a microscope) and I can measure that very easily.
I read a blog post about using "true c" and how you can get a much higher speed that way (https://www.instructables.com/Arduino-is-Slow-and-how-to-fix-it/). I tried it, but with no improvements.
Here is the Arduino code:
int i;
void setup() {
Serial.begin(500000);
#define LED_PIN 8
#define L_STEP_PIN 60 //PF6
#define L_DIR_PIN 61 //PF7
#define L_ENABLE_PIN 56 // Active LOW
#define R_STEP_PIN 54 //PF0
#define R_DIR_PIN 55 //PF1
#define R_ENABLE_PIN 38 // Active LOW
pinMode(LED_PIN , OUTPUT);
digitalWrite(LED_PIN, LOW);
// Left and right motors step pins
pinMode(L_STEP_PIN, OUTPUT);
pinMode(R_STEP_PIN, OUTPUT);
// Left and right motors direction pins
pinMode(L_DIR_PIN, OUTPUT);
pinMode(R_DIR_PIN, OUTPUT);
pinMode(L_ENABLE_PIN, OUTPUT);
pinMode(R_ENABLE_PIN, OUTPUT);
digitalWrite(L_ENABLE_PIN, LOW);
digitalWrite(R_ENABLE_PIN, LOW);
}
void loop() {
if (Serial.available() > 0)
{
Serial.read();
//L_DIR_PIN, HIGH;
PORTF |= _BV(PF7);
//R_DIR_PIN, HIGH;
PORTF |= _BV(PF1);
for (i = 0; i < 100; i++)
{
//L_STEP_PIN, HIGH;
PORTF |= _BV(PF6);
//R_STEP_PIN, HIGH;
PORTF |= _BV(PF0);
delayMicroseconds(200);
//L_STEP_PIN, LOW;
PORTF &= ~_BV(PF6);
//R_STEP_PIN, LOW;
PORTF &= ~_BV(PF0);
}
}
}
And here is the python code:
try:
arduino = open_serial_port(baudrate=500000, timeout=None)
except Exception as e:
raise e
sleep(2)
print(f'Arduino Initialized')
print('Starting Camera...')
cam = camera.Camera()
cam.run()
sleep(1)
img1 = cam.get_img_data()
cv2.imwrite(f'focus_test/test_01.tif', img1)
######## START #########
start = time()
write_i8(arduino, 1)
# take an image
sleep(0.008)
img2 = cam.get_img_data()
elapsed = (time() - start) * 1000
print(f'Elapsed = {elapsed} ms')
cv2.imwrite(f'focus_test/test_02.tif', img2)
I first thought that the main problem is in the Serial.available() or Serial.read() function. But, the ping time using same functions is ok, so that can't be the culprit. It almost seems like Arduino is behaving normally, but for some reason, there is a lag in digital ports. I'm also using ramps 1.6 in the same setup. Can that be a reason?