Arduino and Python one-to-one serial communication

I would like to control a servo motor with Arduino UNO board and Python code.

Through the Python terminal I send a letter: 'p' to go forward by 5 ° and 'm' to go back by 5 °.

If I send the letter 'c' I want to have back the gardi that the engine has at this moment.

For Arduino I use SerialTransfer.h, and for Python pySerialTransfer.

The problem is when i write letter 'p' on Python terminal anything happen with the motor.

Arduino Code:

#include <Servo.h>
#include "SerialTransfer.h"

SerialTransfer trans;

Servo Z;

#define Z_Start 90
#define VALUE 5

char comand = 'd';

bool read = false;

int Z_New;
int Z_Old;

int ControlloFinecorsa(Servo servo_name, int angle) {
  if (angle < 0) {
    trans.txBuff[0] = 'm'; //Min angle value
    trans.send(1);
    return 3;
  }

  if (angle > 180) {
    trans.txBuff[0] = 'M'; //Max angle value
    trans.send(1);
    return 3;
  }

  else {
    return 0;
  }
}


int ServoPosition(Servo servo_name) {
  int position = servo_name.read();
  return position;
}


int ServoRotation(Servo servo_name, int angle, int now) {
  if (LimitSwitch(servo_name, angle) != 3) {  //if the limit switches check is correct, proceed with moving the motor
    //previous position greater than that to be reached
    if (now > angle) {
      //I use a loop to control the speed of the servo
      for(int j = now; j >= angle; j--) { //servo down
        servo_name.write(j);
        delay(20);
      }
    }
    //previous position lower than the one to reach
    if (now < angle) {
      for(int j = now; j <= angle; j++) { //servo rise
        servo_name.write(j);
        delay(20);
      }
    }
    now = angle; //I set the current position as the previous position
    return now;
   }
   
   else if (LimitSwitch(servo_name, angle) == 3) {
    return now;
    
   }
    
}


void setup() {
  Serial.begin(115200);
  trans.begin(Serial);

  //Z Servo start value
  Z.write(Z_Start);
  Z.attach(6);
  Z_Old = Z_Start;

}


void loop() {
  do{
    if (trans.available()) {
      comand = trans.rxBuff[0];
      read = true; 
  }

    else if(trans.status < 0) {
      read = false;
    }
  }
  while(!read);

  
  //know servo position
  if (comand == 'c') {
    int pos = ServoPosition(Z);
    trans.txBuff[0] = pos;
    trans.send(1);
  }

  //Move Servo forward for 5 degree
  if (comand == 'p') {
    Z_New = Z_Old + VALUE;
    Z_Old = ServoRotation(Z, Z_New, Z_Old);
  }

  //Move Servo backward for 5 degree
  if (comand == 'm') {
    Z_New = Z_Old - VALUE;
    Z_Old = ServoRotation(Z, Z_New, Z_Old);
  }

  
}

Python Code:


import serial
import time
from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
    try:
        link = txfer.SerialTransfer('COM6')

        Z_Angle = 90

        while True:
            choose = input("\nChoose one of the following possibilities: \n"
                           "[1] Move Z servo forward\n"
                           "[2] MOve Z servo backward\n"
                           "[3] Know Z servo angle\n"
                           "[0] Uscire\n"
                           "---> ")

            if choose == "1":
                link.txBuff[0] = 'p'
                link.send(1)
                Z_Angle = Z_Angle + 5

            elif choose == "2":
                link.txBuff[0] = 'm'
                link.send(1)
                Z_Angle = Z_Angle - 5

	    elif choose == "3":
		link.txBuff[0] = 'c'
		link.send(1)

		print("Z Servo Angle: ")
		print(link.rxBuff[0])

	    elif choose == "0":
		print("Bye")
		break


            while not link.available():
                if link.status < 0:
                    print('ERROR: {}'.format(link.status))

    except KeyboardInterrupt:
        link.close()

Thanks for your cooperation, and sorry for my bad english

Have you tried printing what is received by the Arduino ?

I know little or nothing about Python, but are you opening the serial port each time before you send a command ? If so, then this will cause many Arduinos to reboot

try using the serial monitor to send the commands to the Arduino
if it works the problem is the Python code

I'm sure the Arduino code works correctly, because I wrote the arduino code first by checking it with the serial monitor and it worked fine.

your Python code used COM6

  1. are you sure this is the correct port?
  2. are you sure the port is available, i.e. nothing else such as the Serial Monitor is already connected too it?

this is a simple terminal emulator in Python

  1. keyboard hits are transmistted to serial port COM7:
  2. serial characters received are displayed on console
# terminal.py - simple terminal emulator - requires pyserial

import serial
import sys
import msvcrt

serialPort = serial.Serial(
    port="COM7", baudrate=115200, bytesize=8, timeout=2, stopbits=serial.STOPBITS_ONE
)
while 1:
    try:
        # serial data received?  if so read byte and print it
        if serialPort.in_waiting > 0:
            char = serialPort.read()
            sys.stdout.write(str(char, 'ASCII'))
        # keyboard hit? if so read key and transmit over serial
        if msvcrt.kbhit():
            serialPort.write(msvcrt.getch())
    except:
        pass

a run using Windows Command Prompt communicating with a target system over COM7:

Microsoft Windows [Version 10.0.19044.1566]
(c) Microsoft Corporation. All rights reserved.

F:\>cd F:\Programming\python\Serial

F:\Programming\python\Serial>python terminal.py

Keyboard based setup and tests of system components
 1: set/display configuration data
 2: System tests
   select test (ESC to exit) ? 1

set/display configuration
 1: display configuration
 2: set system config parameters
 3: set grease shield parameters
 4: LRW32 Lora functions/setup
 5: GSM modem setup and test
 6: set system configuration defaults
 7: set GS control defaults
 8: set GS control test defaults
 9: force Watch dog timeout
 A: RN2483 LoraWAN setup and test
   select test (ESC to exit) ? 1

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