pythoncelerypyserialrs485

Python pyserial use a lot of CPU for simple task on Celery


I'm using Pyserial inside a Celery worker to write every 150ms a packet of max 20 bytes on the serial

Literally the celery worker does nothing except send data on the serial with ser.write(packet) with ser = serial.Serial(COM, 38400, timeout=0.1)

Celery worker

@shared_task(bind=True)
def start_serial_acquisition(self, idObj, porta_COM):
   ser = serial.Serial(COM, 38400, timeout=0.1)
   packer = b'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80'
   time_start = time.monotonic()
   time_stop = time.monotonic()
   while True:
      time_stop = time.monotonic()
      if(time_stop - time_start > 0.149)
         ser.write(packet)
         time_start = time.monotonic()

The main issue is that this simple process, takes an entire core of my two core CPU with the result 50% of the CPU is used just to send data on the serial. The specs of my PC are

PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

I'm using Python 3.10 and the latest version of pyserial and celery v5.3.0

When I stop writing on the serial, the CPU basically goes IDLE with a consumption between 1-2%

I can't find the issue as, I would like to optimize it. I'm using a USB - RS485 converter as serial to communicate data


Solution

  • I am not surprised that the task consumes 100% CPU because the while loop runs forever measuring time, calculating time_stop - time_start and checking whether it is greater than 0.149. You should have something like this instead:

       while True:
           ser.write(packet)
           time.sleep(0.15)