Python - разница между pyserial.write (val = raw_input ()) и pyserial.write (строка)?

Пытаясь выполнить полудуплексную связь между Python (на ПК Win10) и Arduino (Uno), я отправляю некоторые строковые команды с ПК на ARD, и в зависимости от ввода строки чтения отправляю либо специальный оператор, либо эхо. прочитанная информация обратно.

Чтобы проверить это, я написал очень простой набор скриптов для Arduino и Python.

Ардуино:

// Test
// <python_script.py>

// https://github.com/fortruce/fortruce.github.io/blob/master/_posts/2014-8-31-talking-to-arduino-with-python.md

void setup(){
    Serial.begin(9600);
    //Serial.setTimeout(10000); // change from 1s to 10s timeout.
    pinMode(7, INPUT);
}

// ARD sends data to PY
void loop(){
    //Serial.write(0x41);
    //delay(1000);
    while(!Serial.available()){
        //Serial.write(0x01);
        //delay(300);
    }
    //Serial.read(); // read single byte being sent-over

    // <https://www.arduino.cc/reference/en/language/functions/communication/serial/readstring/>
    if(Serial.available()){
        String input = Serial.readStringUntil("\n"); // If there are available bytes to read, them them into a String

        // Functionality appears the same, whether using <readStringUntil("\n")> or <readString()>

        if(input=="*SETUP?"){
            /* Try-catch doesn't exist in C */
            // http://www.cplusplus.com/doc/tutorial/exceptions/
            if(Serial.availableForWrite()){
                Serial.println("ARD told to do Setup!");
            }
        }
        else if(input=="testAN"){
            float val[6]; // Size = 4 bytes per Float, = 4*6 = 24
            for(int i=0; i<6; i++){
                val[i] = analogRead(i);
            }
            if(Serial.availableForWrite()){
                Serial.print("<");
                Serial.print(val[0]);
                Serial.print(",");
                Serial.print(val[1]);
                Serial.print(",");
                Serial.print(val[2]);
                Serial.print(",");
                Serial.print(val[3]);
                Serial.print(",");
                Serial.print(val[4]);
                Serial.print(",");
                Serial.print(val[5]);
                Serial.println(">");
            }
        }
        else{
            if(Serial.availableForWrite()){
                Serial.print("ARD received: {");
                Serial.print(input);
                Serial.println("}.");
            }
        }
        // <https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/>
        Serial.flush(); // wait for outgoing data to finish.
    }
}      
// EOL

Python:

# Test

# https://github.com/fortruce/fortruce.github.io/blob/master/_posts/2014-8-31-talking-to-arduino-with-python.md

import serial, time
import struct

ard = serial.Serial('COM4')

ard.reset_input_buffer()
ard.reset_output_buffer()

### Need a way to break this loop; once we get the info we want, move to the next PY step...
while(True):
    output = raw_input("Type what you want to send and hit 'Enter': ")

    ### Other forms of "output" I have tried:
    #output = "testAN" ### This is what I thought I could send...
    #output = "testAN\n"
    #output = "testAN\r"
    #output = "testAN\n\r"
    #output = "testAN\r\n"

    print("<" + unicode(output) + ">")
    ###print("b")
    ard.reset_output_buffer()
    ###print("c")
    print(ard.write(output))
    #ard.write(b"%s" % output)
    #time.sleep(0.5) # Give the ARD time to read...
    ###print("d")
    #ard.flushInput() # Wait for Input to be of 
    print("e")
    rec = ard.readline().strip("\n") # HUNG HERE
    #rec = ard.read_until("\n") # HUNG HERE

    ard.reset_input_buffer() # Reset input AFTER capture

    print("f")
    #print(rec)
    rec = rec.strip("\n") 
    print("g")
    #print(rec)

    if(">" in rec):
        print(rec) # To be sure...
        break;
    else:    
        print("Echo from ARD is: {%s}." % rec)
    # End if-else
# End while-loop

print("Data was received, now can do next thing!")

# EOL

Как только я поменяю местами

output = raw_input("Input: ") # type 'testAN' and hit 'Enter'

в Python с

output = "testAN" # Constant string

, этот скрипт Python зависает в операторе readline (). Почему это? Я подтвердил, что Write () отправляет одинаковое количество байтов (6) независимо от происхождения.

# e.g.
print(ard.write(raw_input(": "))) # w/input testAN  
# and 
print(ard.write("testAN")) 

оба возвращают 6.

Для справки я использую PySerial 3.4 и Python 2.7.13!

Thomas Solley 13.09.2018 18:10

Arduino выполняет Serial.readStringUntil("\n"), но вы никогда не пишете новую строку со стороны Python, единственный способ, которым этот оператор может завершиться, - это тайм-аут.

jasonharper 13.09.2018 18:25

Джейсон, это хорошее замечание; для записи я попробовал <readString ()> перед переходом к <readStringUntil ()>. Просто добавил это изменение во фрагмент кода Arduino, чтобы другие пользователи, нашедшие этот пост, могли это увидеть.

Thomas Solley 13.09.2018 18:35
readString завершается только по таймауту.
gre_gor 13.09.2018 21:29
0
4
114
0

Другие вопросы по теме