Sending Serial Data through GUI but receiving it late in Arduino

Hello,
I want to control my stepper motor RPM using a scale/slider widget in tkinter (Python). But while sending the data the data is received late
i.e. I move the slider from x-->y stop there and then move from y-->z stop there. My motor rotates at :

x RPM when my slider stops at y
y RPM when my slider stops at z
.
.
and so on

Python code :

from tkinter import *
import time
import serial

y=serial.Serial(port='COM3', baudrate=115200, timeout=0.1)

win=Tk()

win.geometry('550x500')
win.title('Stepper Control')

def speed(val):
    
    a= val+';'
    encodedMessage=a.encode()
    y.write(encodedMessage)
    print(encodedMessage)    
    data=y.readline()
    print (data)

x=StringVar()
slider=Scale(win,variable=DoubleVar(), from_=-200, to=200, orient=HORIZONTAL, command=speed)
slider.place(relx=0.15,rely=0.07,relwidth=0.7)



win.mainloop()

Arduino code :

String StepRPMstr;
String StepRPM;
int RPM;
float pulserate;
float delaytime;
long int delayint;
long int delayint1;


void setup() {
  Serial.begin(115200);
  pinMode(3,OUTPUT);
  pinMode(5,OUTPUT);
  
}

void loop() {
 
 if(Serial.available()>0) {

    StepRPMstr=Serial.readString();
    Serial.setTimeout(10);
    Serial.println(StepRPMstr);

    RPM =StepRPMstr.toInt();
    pulserate=(800/60)*RPM;
    delaytime=(1000000/pulserate)*0.5;
    delayint = (long int)delaytime;
    delayint1 = abs(delayint);
    //Serial.println(delaytime);
    //Serial.println(delayint1);
 }

  if(RPM>0) {

        digitalWrite(3,HIGH);

          for(int x=0; x<800; x++) {
              digitalWrite(5,HIGH);
              delayMicroseconds(delayint);
              digitalWrite(5,LOW);
              delayMicroseconds(delayint);
              //Serial.println('G');
          }
   }

   if(RPM<0) {

        digitalWrite(3,LOW);

          for(int x=0; x<800; x++) {
              digitalWrite(5,HIGH);
              delayMicroseconds(delayint1);
              digitalWrite(5,LOW);
              delayMicroseconds(delayint1);

          }
   }
   
} 

I guess that the semicolon shall be used as EOM. If the Arduino does not know that then it may wait for a timeout instead.

I looked at this and though the "command" in the scale is perhaps a good way to go I decided to try displaying the scale values in a separate thread, this does not stop you from modifying things a little to include the "speed" method. I also agreed with DrDiettrich and replaced the semi colon with a newline character.

The thread is designed to display the most recent value once only and the "sleep" is only there to remove a little jitter so can be commented out if you want.

Actually the test code resembles something I posted yesterday with the Arduino echoing back the resulting value.

PY

from tkinter import *
from threading import *
import serial
import time

root = Tk()
root.title('Stepper Control')

root.geometry("330x470")

flush_system="<>".encode()

ser = serial.Serial('COM3',115200)
ser.timeout=1
ser.read_until(flush_system)

s1=StringVar()

def thread_start():
   
    t1=Thread(target=display_data,daemon=True)
    t1.start()

def  display_data():
	
	new_val=0
	
	while True:

		time.sleep(0.2)

		s1=slide_1.get()
	
		old_val=s1

		if old_val != new_val:
		
			ser.write(f"{s1}\n".encode())
			input_string=ser.readline().strip().decode("utf-8")
			#txt.delete("1.0",END)
			txt.insert(END,input_string + '\n')

		new_val=old_val

def clear():
	txt.delete("1.0",END)

slide_1 = Scale(root, from_= -200, to= 200,orient=HORIZONTAL,length=300)
slide_1.grid(row=0,column=0)

txt=Text(root,relief="sunken",borderwidth=5,width=40)
txt.grid(row=1,column=0)

btn = Button(root,text="Clear",command=lambda:clear())
btn.grid(row=2,column=0)

thread_start()

root.mainloop()

ARDUINO

int my_integer;

void setup() {

  Serial.begin(115200);
  Serial.print("<>");
}

void loop() {
  
 if (Serial.available()) {
  
    my_integer = Serial.readStringUntil('\n').toInt(); 
   
    Serial.println(my_integer);
    
 }

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.