Чтение данных в реальном времени из последовательного порта из Arduino в скрипт Python - PullRequest
0 голосов
/ 30 октября 2019

Я пытаюсь прочитать данные из Arduino через Pyserial lib. Я столкнулся с проблемой, когда он запрещает доступ к COM-порту для чтения данных.

Скрипт python представляет собой программу OpenCV для отслеживания объекта, он запрашивает ограничивающий прямоугольник, а затем отслеживает этот прямоугольник в потоке камеры. Он также выведет на экран расстояние, считываемое ИК-датчиком, подключенным к Arduino.

Я попытался очистить код Arduino и снова его прошить, что не помогло. Я закрыл последовательный монитор, который, казалось, однажды помог, но по какой-то причине он снова не заработал.

Код Arduino:

#include <SharpIR.h>
SharpIR DETECTORsensor( SharpIR::GP2Y0A21YK0F, A0 );

void setup()
{
  Serial.begin( 9600 );
}

void loop()
{
  int distance = DETECTORsensor.getDistance(); 
  Serial.println( distance );
  delay(500);
}

Код Python выглядит следующим образом:

import cv2
import sys
import serial


if __name__ == '__main__' :

    # Set up tracker.
    tracker = cv2.TrackerMIL_create()

    # Read video
    video = cv2.VideoCapture(0)

    # Exit if video not opened.
    if not video.isOpened():
        print ("Could not open video")
        sys.exit()

    # Read first frame.
    ok, frame = video.read()
    if not ok:
        print ('Cannot read video file')
        sys.exit()



#Define ROI
    bbox = cv2.selectROI(frame, False)

    # Initialize tracker with first frame and bounding box
    ok = tracker.init(frame, bbox)

    while True:
        # Read a new frame
        ok, frame = video.read()
        if not ok:
            break

        # Start timer, FPS only
        timer = cv2.getTickCount()

        # Update tracker
        ok, bbox = tracker.update(frame)

        # Calculate Frames per second (FPS)
        fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer);

        #calculate Distance from Raspi
        focallength = 480.20
        knownwidth = 30.480 #Almost the same size as A4 paper
        perwidth = bbox[2] #This is what will update every frame, unable to update for now
        RaspiDist = (knownwidth*focallength)/perwidth

        #Calculate distance from IR sensor
        ser_data = serial.Serial("COM3",9600)

        # Draw bounding box
        if ok:
            # Tracking success
            p1 = (int(bbox[0]), int(bbox[1]))
            p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
            cv2.rectangle(frame, p1, p2, (0,255,255), 2, 1)
        else :
            # Tracking failure
            cv2.putText(frame, "Tracking failure detected", (100,80), cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)

#Display tracker type on frame
        cv2.putText(frame, "MIL Tracker", (0,20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0,255,255), 2);

#Display FPS on frame
        cv2.putText(frame, "FPS : " + str(int(fps)), (0,50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0,255,255), 2);

#Display Distance on frame
        cv2.putText(frame, "RaspiDistance : " + str(int(RaspiDist))+" cms", (0,75), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0,255,255), 2);
        cv2.putText(frame, "IRDistance : " + str(int(ser_data)), (0,100), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0,255,255), 2);

        # Display result [2] 
        cv2.imshow("Tracking", frame)

        # Exit if ESC pressed
        k = cv2.waitKey(1) & 0xff

# Destroy all windows
cv2.destroyAllWindows()

Ошибка:

Файл"C: \ Users \ XXX \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ serial \ serialwin32.py", строка 62, в открытом запросе SerialException ("не удалось открыть порт {! R}: {! R}".format (self.portstr, ctypes.WinError ()))

SerialException: не удалось открыть порт «COM3»: PermissionError (13, «Доступ запрещен», None, 5)

Ответы [ 2 ]

1 голос
/ 31 октября 2019

Вот минимальный код, который вы можете использовать для тестирования ваших последовательных портов. Код Arduino

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int distance = 123;
  Serial.println(distance);
  delay(500);
}

и скрипт Python

from serial import Serial

port = "COM3"
baudrate = 9600

with Serial(port=port, baudrate=baudrate, timeout=1) as port_serie:
    if port_serie.isOpen():
        port_serie.flush()
        for i in range(20):
            try:
                ligne = port_serie.readline()
                print(str(ligne))
            except:
                print("Exception")
        port_serie.close()

Этот минимальный код выполняется только на 20 итерациях. Я удалил while True, потому что мне не нравятся возможные бесконечные циклы для отладки. Если скрипт работает, вы можете использовать while, включить все ваши видео материалы и ваше обнаружение расстояния на Arduino

1 голос
/ 30 октября 2019

Я подозреваю, что это потому, что у вас есть ser_data = serial.Serial("COM3",9600) внутри вашего основного цикла. Это означает, что во втором цикле он попытается открыть соединение, которое уже используется. Так что это отрицается. Вы должны убрать эту строку из основного цикла и правильно закрыть ее, когда скрипт завершится.

В качестве альтернативы вы можете использовать

with serial.Serial() as ser:
    [loop here]

Вы также должны знать, что в настоящее время ваш код не читает никаких данных из последовательного соединения. Для этого вам нужно использовать read()

x = ser.read()          # read one byte
s = ser.read(10)        # read up to ten bytes (timeout)

Я бы посоветовал сначала создать небольшой скрипт, который может считывать данные IR, чтобы вы знали, что это работает. Документация очень полезна, прочитайте ее здесь .

...