Pyserial и Arduino

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

Arduino:

#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER,8,9); 

void setup() {
  Serial.begin(9600);
  stepper.setMaxSpeed(1000.0);
  stepper.setAcceleration(700.0);
}

void loop() {
  int val = 0;
  if(Serial.available()){
    val = map(Serial.parseInt(), 0, 1280, 0, 551); 
    Serial.println(val);
  }
  stepper.runToNewPosition(val);
}

Python:

# source: http://www.steinm.com/blog/motion-detection-webcam-python-opencv-differential-images/

import cv2
import numpy as np
import serial
import time

def diffImg(t0, t1, t2):
    d1 = cv2.absdiff(t2, t1)
    d2 = cv2.absdiff(t1, t0)
    dif = cv2.bitwise_and(d1, d2)
    return np.fliplr(dif)

cam = cv2.VideoCapture(0)  

#winName = "Movement Indicator" #camera window
#cv2.namedWindow(winName, cv2.WINDOW_NORMAL)

# Read three images first:
t_minus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)

h, w = t.shape

winTest = "Test Window" #test window
cv2.namedWindow(winTest, cv2.WINDOW_NORMAL)

thresh = 100

ser=serial.Serial('/dev/cu.usbmodem1411',9600,timeout=0)
time.sleep(2)

while True:

    img = diffImg(t_minus, t, t_plus)

#    cv2.imshow(winName, img )

    nz = np.transpose(np.nonzero(img>thresh))
    a = 0
    b = 0
    c = 0
    d = 0
    avg=0
    if nz.size>0:
        a,b = nz[0]
        c,d = nz[-1]
        avg = (b+d)/2
        if 0<=avg and avg<=1280:
            print avg
            ser.write(str(int(avg))+" ") 

    test = np.zeros((h,w))

    cv2.rectangle(test, ((avg-5),a), ((avg+5),c), (255), -1)
    cv2.imshow(winTest, test )

    # Read next image
    t_minus = t
    t = t_plus
    t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
    print ser.readline();   


    key = cv2.waitKey(10)
    if key == 27:
       cv2.destroyWindow(winName)
       ser.close()
       break

print "Goodbye"

Это работает нормально, но иногда " val " принимает какое-то нелепое значение, скажем, 7182, и двигатель выходит из-под контроля. Я понимаю, что могу проверить значения с помощью оператора if, прежде чем писать на шаговый двигатель, но я думаю, что моя проблема заключается в чтении и записи на Arduino.

Моя другая проблема заключается в том, что я чувствую, что Arduino не получает некоторые данные, отправленные ему через последовательное соединение. Это трудно сказать, так как Serial.print() работает медленно и в основном не доходит до моего терминала до того, как он уже был переписан.

, 👍-1

Обсуждение

`Serial.print() работает медленно " - попробуйте использовать более быструю скорость передачи данных, например 115200?, @Nick Gammon


1 ответ


0

Комментарий мистера Гэммона об использовании более высокой скорости передачи данных-отличная идея.

Вы также, похоже, отправляете номер в виде строки. Отправка целого числа в виде двоичных данных (с использованием модуля структуры python) также уменьшит объем данных, которые необходимо отправить - значительно для больших чисел.

import struct

...

ser.write(struct.pack('I',int(avg)))

На стороне Arduino

uint8_t buffer[4];
uint32_t position;

if (my_serial.read(buffer, sizeof(uint32_t)) == sizeof(uint32_t))
    memcpy(&position, buffer, sizeof(uint32_t));

// alternatively in one step, without error checking
my_serial.read(&position, sizeof(uint32_t));

Это предполагает, что требуется 32-разрядное целое число.
Возможно, вам нужно только короткое сообщение без подписи - это вдвое уменьшило бы сумму, необходимую для передачи.

,