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() работает медленно и в основном не доходит до моего терминала до того, как он уже был переписан.
@Shahrod Khalkhali, 👍-1
Обсуждение1 ответ
Комментарий мистера Гэммона об использовании более высокой скорости передачи данных-отличная идея.
Вы также, похоже, отправляете номер в виде строки. Отправка целого числа в виде двоичных данных (с использованием модуля структуры 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-разрядное целое число.
Возможно, вам нужно только короткое сообщение без подписи - это вдвое уменьшило бы сумму, необходимую для передачи.
- Не удается связаться с ардуино с помощью python (Windows)
- Последовательная связь Arduino с Python: отправка массива
- Построение графика на Python с использованием Tkinter Canvas
- Как отправить целое число через pyserial с Python на Arduino и получить тот же результат?
- Сброс последовательного порта Arduino в последовательном мониторе и Python
- Отправка числа с плавающей запятой из python в arduino
- Serial Comm. проблема синхронизации между Arduino и Pyserial
- Связь между Python и Arduino ненадежна
`Serial.print() работает медленно " - попробуйте использовать более быструю скорость передачи данных, например 115200?, @Nick Gammon