moving one servo via mouse, x-axis provided by python

Hi, when i move the mouse, python generates the degree for the servo to jump to, then python writes the number in the serial port. Arduino reads the serial, then uses that number to move the servo to the respected degree.
Result: the servo does move when i move the mouse, but it first jerks a lot and then jumps to either 180 degrees and 0 degrees only. The python code seems to be generating the correct number, perhaps my arduino code needs a fix! I will paste the python code at the bottom in case you would like to see it.

Thanks

Arduino code:

#include <Servo.h>
Servo myservo;


int pin=9;


void setup() { 
  myservo.attach(9);
  pinMode(pin, OUTPUT); 
  digitalWrite (pin, LOW);
  Serial.setTimeout(100);
  Serial.begin(9600);
}
 
void loop() {
  int number;
  int currentPos; 
  
  if (Serial.available()) 
    currentPos = myservo.read();
    number = Serial.parseInt();
    for (number = currentPos; currentPos <= number; number += 1){
    myservo.write(number);
    delay(1);
  }
  for (number = currentPos; currentPos >= number; number -= 1){
    myservo.write(number);
    delay(1);
  }
}

python code:

import serial
import math
import time
from pynput.mouse import Button, Controller, Listener
mouse = Controller()

arduinoData = serial.Serial('com3',9600) 


def on_move(x, y): 
   degree = (x/(1440/180))
   arduinoData.write(str(degree).encode())
   print(x, degree)


# Collect events until released 
with Listener( on_move=on_move) as listener : listener.join()



while True:
#loop forever
    time.sleep(2)
    currentPos = myservo.read();

That is NOT going to give you the current position. It is going to give you the last position you told the servo to go to, which you SHOULD remember.

    for (number = currentPos; currentPos <= number; number += 1){
    myservo.write(number);
    delay(1);
  }

With the stupid delay(), of course the servo is going to lag way behind, and always be trying to catch up.

Of course, the conditions of the for loop are indicative of not being the sharpest crayon in the box. That for loop will only iterate once - never more, never less.

If there is no serial data to read, just where are you moving the servo to? Why are you moving it at all?

The answer to the first question is that you haven’t a clue, because number and currentPos have not been initialized if there is no serial data to read.

You wait for a number to arrive and store it in ‘number’. Then in the ‘for’ loops you store ‘currentPos’ into ‘number’, destroying the number you read.

If you want to keep track of “currentPos” you should make that global (outside of any function) or declare it ‘static’.

Try this instead:

#include <Servo.h>
Servo myservo;

const int pin = 9;
int CurrentPosition = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(pin, OUTPUT);
  myservo.attach(pin);
  Serial.setTimeout(100);
}

void loop()
{
  int newPosition;

  if (Serial.available()) 
  {
    newPosition = Serial.parseInt();

    if (newPosition < 0)
        return;

    if (newPosition > 180)
        return;
  
    for (; CurrentPosition < newPosition; CurrentPosition++)
    {
      myservo.write(CurrentPosition);
      delay(1);
    }
  
    for (; CurrentPosition > newPosition; CurrentPosition--)
    {
      myservo.write(CurrentPosition);
      delay(1);
    }
  }
}

Thanks you all for you help and patience, johnwasser i tried the arduino code, didnt work. Allow me to ask this question in a better way, originally i have python randomly set a degree and it works, the servo moves to that degree.
Now i wanted to try python generating a degree to the serial port based on my mouse movement.
Here’s the code for the arduino that worked:

#include <Servo.h>

Servo myservo;

int pin = 9;

void setup() {
  myservo.attach(9);
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
  Serial.setTimeout(100);
  Serial.begin(9600);
}

void loop() {
  int number;

  if (Serial.available()) {
    number = Serial.parseInt();
    myservo.write(number);
    delay(0.5);
  }
}

Here is the python code the randomizes the degree:

import serial
import time
import random

arduinoData = serial.Serial('com3',9600)  

# Let Arduino some time to reset
time.sleep(2)

while True:
    low = 0; high = 180
    ran_number = random.randint(low, high)
    print(ran_number)
    arduinoData.write(str(ran_number).encode())

    time.sleep(1)

Now, if i left the arduino code the same and changed the python code so it generates the degree based on mouse movement, shouldnt it work? but it doesnt

import serial
import math
import time
from pynput.mouse import Button, Controller, Listener
mouse = Controller()

arduinoData = serial.Serial('com3',9600) 

def on_move(x, y): 
   degree = (x/(1440/180))
   arduinoData.write(str(degree).encode())
   print(x, degree)


# Collect events until released 
with Listener( on_move=on_move) as listener : listener.join()



while True:
#loop forever
    time.sleep(2)

Question is shouldnt this work?

Have a look at this Python - Arduino demo and at Serial Input Basics - simple reliable ways to receive data.

...R

Is your current python script sending an int? If not, why are you calling parseInt()? It looks to me like your python script is now sending a float, so calling parseFloat() seems a more reasonable thing to do.