Попытка отслеживать последовательный вывод строки для запуска функции, по-видимому, выводится совпадающая строка, но функция не запускается

Я работаю над своим вторым проектом Arduino и немного застрял.

Я запускаю модуль PIR из моего Arduino Uno со следующим скетчем:

/* 
* Тест датчика PIR
 */

 int pirPin = 6;

 int minSecsBetweenEmails = 60; // 60 секунд

 long lastSend = -minSecsBetweenEmails * 1000l;

 void setup() 
 {
  pinMode(pirPin, INPUT);

  Serial.begin(9600);
 }

 void loop() {
  long now = millis();
  if (digitalRead(pirPin) == HIGH)
    {
       if (now > (lastSend + minSecsBetweenEmails * 1000l))
        {
            Serial.println("MOVEMENT");
            lastSend = now;
        }
      else
        {
          Serial.println("Too soon");
        }
    }
        delay(500);
 }

Я отслеживаю порт COM3, используя JupyterLab с PySerial.

import time
import serial
import smtplib

to = '[email protected]'
GMAIL_USER = '[email protected]'
GMAIL_PASS = '**********'

SUBJECT = 'MOTION pir'
TEXT = 'PIR sensor detected motion'

ser = serial.Serial('COM3', 9600)

def send_email():
    print("Sending Email")
    smtpserver = smtplib.smtp("smtp.gmail.com",587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(GMAIL_USER, GMAIL_PASS)
    header = str('To:' + TO + '\n' + 'From: ' + GMAIL_USER)
    header = header + '\n' + 'Subject:' + SUBJECT + '\n'
    print (header)
    msg - header + '\n' + TEXT + ' \n\n'
    smtpserver.sendmail(GMAIL_USER, TO, msg)
    smtpserver.close()

while True:
        message = ser.readline()
        print(message.decode('utf-8'))
        if message[0] == 'MOVEMENT' :
            send_email()
            time.sleep(0.5)

Я считаю, что моя проблема связана с функцией ser.readline(). Я читал документы, они, кажется, говорят, что мне нужно предоставить какую-то конечную точку или тайм-аут для функции, обеспечивающей EOF, но моя цель состояла в том, чтобы иметь

if message [0] == 'MOVEMENT' :  

непрерывно оценивать выходные строки COM3...

Мы будем очень признательны за любые комментарии.

EDIT: Спасибо всем троим за помощь! Изменив Python, как показано ниже, я смог выполнить оператор if message[0] == 'MOVEMENT' :

Python должен был быть:

import time
import serial
import smtplib

to = '[email protected]'
GMAIL_USER = '[email protected]'
GMAIL_PASS = '**********'

SUBJECT = 'MOTION pir'
TEXT = 'PIR sensor detected motion'

ser = serial.Serial('COM3', 9600)

def send_email():
    print("Sending Email")
    smtpserver = smtplib.smtp("smtp.gmail.com",587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(GMAIL_USER, GMAIL_PASS)
    header = str('To:' + TO + '\n' + 'From: ' + GMAIL_USER)
    header = header + '\n' + 'Subject:' + SUBJECT + '\n'
    print (header)
    msg - header + '\n' + TEXT + ' \n\n'
    smtpserver.sendmail(GMAIL_USER, TO, msg)
    smtpserver.close()

while True:
        message = ser.readline()
        print(message)
        if message == b'MOVEMENT\r\n' :
            send_email()
            time.sleep(0.5)

, 👍0

Обсуждение

Используйте последовательную консоль, чтобы увидеть, что отправляет Arduino. Если он отправляет то, что вы ожидаете, то он работает правильно, ваша проблема заключается в вашем коде Python, и ваш вопрос не относится к этому сайту. Если он _не_ отправляет то, что вы ожидаете, удалите все материалы Python/SMTP из своего вопроса и сосредоточьте его на эскизе Arduino., @Edgar Bonet

Строка чтения обычно также считывает символы конца строки. Вы уверены, что это не так?, @KIIV

И вы уверены, что не сравниваете первый символ сообщения со всей строкой «ДВИЖЕНИЕ»?, @KIIV

Обратите внимание, что ваш тест времени завершится ошибкой, когда millis() перевернется. Вам лучше написать if (now - lastSend > minSecsBetweenEmails * 1000l), что безопасно при переносе., @Edgar Bonet

Эдгар, спасибо за предупреждение о пролонгации millis(). Думаю, я неправильно понял широту этого конкретного сообщества StackExchange, у меня сложилось впечатление, что, поскольку я имею дело с конкретной реализацией Arduino, это будет уместно здесь, но я думаю, что нет. Вывод Uno - это именно то, что я ожидаю, поэтому я думаю, что это скорее проблема Python. KIIV, что касается вашего первого комментария, я пытался добавить символы конца строки в строку, так как я получаю правильный вывод от Uno, но пока безуспешно., @Dylan Shroll-Tews


1 ответ


Лучший ответ:

1

Вы путаете readlines() с readline(). Первый возвращает массив строк, второй — одну строку. Вам нужно удалить [0], поскольку вы не работаете с массивом строк, и вам нужно включить окончания строк, которые отправляет Arduino:

while True:
    message = ser.readline()
    print(message.decode('utf-8'))
    if message == 'MOVEMENT\r\n' :
        send_email()
        time.sleep(0.5)
,

Спасибо Маженко. Вы правы в моей путанице между этими функциями. Я попытался добавить символы конца строки, но еще не выполнил оператор if, поэтому я собираюсь продолжить расследование, где я облажался., @Dylan Shroll-Tews