Проблемы с отправкой данных на Arduino из Python с помощью pySerial

Я пытаюсь отправить «1» или «0» на свой Arduino в Python с помощью pySerial, чтобы с моего Arduino я мог считывать все, что отправляет программа Python, а затем включать и выключать реле в зависимости от того, что оно считывает с Python.

Вот код Python:

import cv2
import imutils
import threading
import time
import serial

Arduino = serial.Serial("COM7")
Arduino.baudrate = 9600

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

_, start_frame = cap.read()
start_frame = imutils.resize(start_frame, width=500)
start_frame = cv2.cvtColor(start_frame, cv2.COLOR_BGR2GRAY)
start_frame = cv2.GaussianBlur(start_frame, (21, 21), 0)

alarm = False
alarmMode = False
alarmCounter = 0

def beep_alarm():
    global alarm
    for i in range(5):
        if not alarmMode:
            break
        print("HE MOVIN HE MOVIN")
        Arduino.write(str.encode("1"))
    alarm = False
    Arduino.write(str.encode("0"))

while True:
    _, frame = cap.read()
    frame = imutils.resize(frame, width=500)
    if alarmMode:
        frameBW = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        frameBW = cv2.GaussianBlur(frameBW, (5, 5), 0)

        difference = cv2.absdiff(frameBW, start_frame)
        threshhold = cv2.threshold(difference, 25, 255, cv2.THRESH_BINARY)[1]
        start_frame = frameBW

        if threshhold.sum() > 300:
            alarmCounter += 1
        else:
            if alarmCounter > 0:
                alarmCounter -= 1

        cv2.imshow("Cam", threshhold)
    else:
        cv2.imshow("Cam", frame)

    if alarmCounter > 20:
        if not alarm:
            alarm = True
            threading.Thread(target=beep_alarm).start()

    keypress = cv2.waitKey(30)
    if keypress == ord("t"):
        alarmMode = not alarmMode
        alarmCounter = 0
    if keypress == ord("q"):
        alarmMode = False
        break

cap.release()
cv2.destroyAllWindows()

По сути, это программа обнаружения движения. Если она обнаруживает, что я двигаюсь, она должна отправить '1' на Arduino, где она затем включает реле.

Вот код Arduino:

int relay = 11;
bool moving = false;

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(1);
  pinMode(relay,OUTPUT);
  digitalWrite(relay, LOW);
}
void loop() {
  while (Serial.available()) {
    if (Serial.read() > 0) {
      while (!Serial.available()) {
        if (moving == false) {
          digitalWrite(relay, LOW);
          delay(100);
          moving = true;
        } else {
          digitalWrite(relay, HIGH);
          delay(100);
          moving = false;
        }
      }
    }
    digitalWrite(relay,LOW);
    delay(100);
  }
}

, 👍0

Обсуждение

можете ли вы успешно отправлять данные с помощью последовательного монитора?, @jsotola


1 ответ


1

Вы не уточнили, в чем именно проблема, но я уже вижу ошибку, вероятно, проблема именно в этом.

Вы отправляете строку «0» или строку «1» из Python. Поскольку это строка — в отличие от числа в некотором двоичном формате — это означает, что она закодирована как текст ASCII. Посмотрите на таблицу ASCII, например, здесь. Вы обнаружите, что символ «0» имеет десятичное значение (DEC) 48. «1» — это десятичное значение 49.

На стороне Arduino у вас есть Serial.read() > 0. Serial.read() возвращает целое число, то есть десятичное число (или, точнее, его двоичное представление). Таким образом, вы получили либо 48 > 0, либо 49 > 0, что всегда верно. Помните о разнице между кодировкой ASCII и двоичной кодировкой целых чисел.

Вы можете заменить указанное выше на

if(Serial.read() == '1'){

Это проверяет, получили ли вы символ (в кодировке ASCII!) '1' (одинарные кавычки предназначены для символов).

Примечание: похоже, вы хотите включать и выключать реле, пока не будет отправлен другой символ. В настоящее время вы переключаете реле 10 раз в секунду. Это много для реле, особенно если вы переключаете высокие напряжения (например, сетевое питание). Вы должны знать, что это может вызвать проблемы с вашим реле через некоторое время.

,