为什么串行read(1)在接收到字符后继续等待直到超时?

时间:2019-05-13 22:50:34

标签: python io pyserial

以下代码通过串行接口与硬件通信。通讯成功(硬件动作并报告了正确的位置),除了几乎不考虑s.timeout的设置(s.timeout必须至少为3s)之外,读命令始终花费大约s.timeout秒。 >

我想知道如何更改此代码,以便在仅接收到一个字符后,read命令将立即返回。

import serial # installed as pyserial
import time, io

try:
    # Best guesses for an undocumented serial device
    s = serial.Serial()
    s.port = 'COM1'
    s.baudrate = 9600
    s.timeout = 5
    s.open()

    # Device begins 18s init routine when serial communication established
    sio = io.TextIOWrapper(io.BufferedRWPair(s,s))
    time.sleep(18)
    start = time.time()
    dat = sio.read(1)
    print('Initial position is %s (%0.3fs reply)' % (dat, time.time()-start))

    # Move device from initial position to Position 2
    sio.write('2')
    sio.flush()
    start = time.time()
    dat = sio.read(1)
    print('New position is %s (%0.3fs reply)' % (dat, time.time()-start))

finally:
    del sio
    s.close()

输出:

Initial position is 0 (5.008s reply)
Moved to position 2 (5.003s reply)

2 个答案:

答案 0 :(得分:0)

在这段代码中,有两件事对我来说很奇怪。

  1. 串行端口用缓冲区包装,但是如果您要逐个字符地控制硬件,那可能就不是您想要的。
  2. new_hash = Hash.new hash.each do |name , category| if new_hash.key?(category) new_file[category] << name else new_hash[category] = [name] # <- must be an array end end 应该用于在逻辑上将两个单工流组合成一个双工流。但是,BufferedRWPair类已经是双工的。

我会尝试完全删除SerialTextIOWrapper,并直接调用BufferedRWPair类的读写方法。

答案 1 :(得分:0)

当我直接使用串行对象而不是通过TextIOWrapper时,我能够从read(1)获得预期的行为,如下面的代码所示。 time.sleep()不再是必需的,但我保留了它,以便可以将代码输出与原始文章的代码进行比较。

我正在使用Python 3.7.3,并且io.TextIOWrapper的文档是从io.TextIOBase继承的,没有明确指出read(N)在读取N个字符后会停止阻塞,尽管我认为应该这样做是合理的。实际上,文档似乎暗示read(size = 1)是正确的实现,尽管以这种方式调用read会导致“ read()不带关键字参数”错误。

我对直接使用串行对象感到满意,但希望有人可以为其他可能需要TextIOWrapper的人回答N字符问题。

const [match, setMatch] = useState();
const [search, setSearch] = useState('');
const [query, setQuery] = useState(4749875544)

useEffect(() => {
    getData();
}, [query]);
const getData = async () => {
    const response = await 
fetch(`https://api.opendota.com/api/matches/${query}`)
    const result = await response.json();
    setMatch(result);
}   
}
return (
    <div className="App" >
        <form onSubmit={getSearch}
            className="search-form">
            <input className="search-bar"
                type="text"
                value={search}
                onChange={searchInput}
            />
            <Button as="input"
                type="submit"
                value="Submit" />
        </form>
        <li>
        {
      Object.keys(match).map((oneKey,i)=>{
        return (
            <li key={i}>{match[oneKey]}</li>
          )})
        }
        </li>
    </div>
)}

输出:

import time, serial

try:
    s = serial.Serial()
    s.port = 'COM1'
    s.baudrate = 9600
    s.timeout = 20
    s.open()

    time.sleep(18)
    start = time.time()
    dat = s.read(1)
    print('Initial position is %s (%0.3fs reply)' % \
          (dat.decode('utf-8'), time.time()-start))

    s.write('2'.encode())
    s.flush()
    start = time.time()
    dat = s.read(1)
    print('New position is %s (%0.3fs reply)' % \
          (dat.decode('utf-8'), time.time()-start))

finally:
    s.close()