0

The above script is supposed to take in user input as a string. The string will look something like this "120,50" where 120 is x coordinate and 50 is y coordinate. I wrote a function called “judge” that will take the user input, split it in two (x and y) and then check if either x or y are more than 127 or less than -127. If that is the case, it should add or subtract 127 from the x/y value. This is done to get the difference. It then adds the 127 (or subtracts) that it took originally to get the difference. After this calculation, the values are sent to an arduino where the mouse is moved accordingly.

main.py on host

import serial, serial.tools.list_ports
import win32api
from time import sleep

# print list of available comports
ports = list(serial.tools.list_ports.comports())

for _ in ports:
    print(_)


# establish connection with given comport
comport = input("Enter comport: COM")
ser = serial.Serial(f"COM{comport}", 115200)

# send coordinates in bytes
def write_read(x):
    ser.write(x.encode("utf-8"))

def judge(num, append_string_x, append_string_y):
    x, y = num.split(",")

    if int(x) > 127:
        append_string_x = str(int(x) - 127)
        # ADD 127 AFTER SENDING
        write_read("127,0")
        sleep(0.01)  # Sleep is used to circumvent a bug I found

    elif int(x) < -127:
        append_string_x = str(int(x) + 127)
        # SUBTRACT 127 AFTER SEND
        write_read("-127,0")
        sleep(0.01)  # Sleep is used to circumvent a bug I found

    else:
        append_string_x = str(x)

    if int(y) > 127:
        append_string_y = str(int(y) - 127)
        # ADD 127 AFTER SENDING
        write_read("0,127")
        sleep(0.01)  # Sleep is used to circumvent a bug I found

    elif int(y) < -127:
        append_string_y = str(int(y) + 127)
        # SUBTRACT 127 AFTER SENDING
        write_read("0,-127")
        sleep(0.01)  # Sleep is used to circumvent a bug I found

    else:
        append_string_y = str(y)

    x_y =  f"{append_string_x},{append_string_y}"
    write_read(x_y)
    sleep(0.01)  # Sleep is used to circumvent a bug I found


# main while loop
while True:
    num = input("Enter a number: ")
    judge(num, append_string_x="", append_string_y="")

main.c on arduino

#include "HID-Project.h"

void setup() {

  Serial.begin(115200);
  Serial.setTimeout(1);  // This shit almost gave me a heart attack
  Mouse.begin();

}

void loop() 
{
    if(Serial.available() > 0)
    {
        String str = Serial.readStringUntil(',');
        int dx = str.toInt();
        int dy = Serial.parseInt();
        mouse_move(dx, dy);
    }
}

void mouse_move(int dx, int dy)
{
  Mouse.move(dx, dy);
}

Behavior WITHOUT the sleep(0.01) call in main.py

behavior.jpg

Why is there y-axis movement when the sleep(0.01) call isn't included in main.py?

Edit: I am using Arduino Micro atmega32u4 if that helps.

zebra14420
  • 51
  • 1
  • 2
  • 7
  • Just took a quick glance through the pyserial docs -- what if you put a `ser.flush()` call at the end of `write_read`? – Samwise Feb 01 '22 at 05:25
  • 1
    In general, when dealing with serial ports without flow control you may get partial reads. A sleep can overcome that, but it would be better to frame the data, or use some kind of delimiter to make sure you get all that data in sync. – Keith Feb 01 '22 at 05:43
  • How is your graph created? Why does your graph show a Y component, but the numbers to the right don't? Also, the green lines have the same X length for all X >= 128 – mmixLinus Feb 01 '22 at 09:31

1 Answers1

0

There is no "end-of-number" character between your ser.writes. This may cause numbers to arrive adjacent to each other, causing your read functions to read incorrect integers.

write_read("0,-127")
...
x_y =  f"{append_string_x},{append_string_y}"
write_read(x_y)

So -127 and x will be read on the Arduino side concatenated (as one string).

You could fix this by sending additional separators ,:

write_read("0,-127,")
mmixLinus
  • 1,646
  • 2
  • 11
  • 16