海阳 发表于 2013-8-16 23:50:35

串口数据读不出!开一下监视器才能读出来,求助!

本帖最后由 海阳 于 2013-8-17 20:29 编辑

我遇到个奇怪的问题。关于串口通讯的。

串口数据读不出!开一下串口监视器再读就可以了。

MEGA 2560板,用USB线连电脑。

以下程序非常简单。

板卡每秒打印12345 到串口上,PC端每隔一秒从COM4上读并打印出来。

直接用ruby程序读,读不到数据,一直卡在readline那一行,readlines ,gets啥都不行

如果我先用IDE自带的端口监视器看一下。
再执行我的ruby代码。就可以正常运行并打印出来。

然后我重新插拔USB线。再运行我的代码。就会卡死在readlines那一行。
getc也不行。用serialport类或FILE都不行。

有高手 来指导 我一下吗?我是个初学者。谢谢啦。



void setup()
{
Serial.begin(9600);

}
void loop()
{

Serial.println(12345);

delay(1000);
}


#!/usr/bin/ruby
require 'serialport'

sp = SerialPort.new "com4", 9600
while true
puts sp.readline
sleep 1
end





海阳 发表于 2013-8-17 10:00:39

顶下,这个应该是很常用的吧。居然我这个也搞不定。

Fortware 发表于 2013-8-17 10:04:49

你用的RUBY ?换个串口试试

pathletboy 发表于 2013-8-17 10:30:32

看看板子上有没跳线,uno上有个跳线关于自动重启的,可能和这个有关。

海阳 发表于 2013-8-17 10:46:21

Fortware 发表于 2013-8-17 10:04 static/image/common/back.gif
你用的RUBY ?换个串口试试

也不行啊,我换了能电脑都不行。不管是USB线,还是用蓝牙串口都一样。
只要是USB上重新插拔一次,都要开监视器再运行程序。。。太郁闷了。:L

海阳 发表于 2013-8-17 11:12:37

pathletboy 发表于 2013-8-17 10:30 static/image/common/back.gif
看看板子上有没跳线,uno上有个跳线关于自动重启的,可能和这个有关。

http://arduino.cc/en/uploads/Main/ArduinoMega2560_R3_Front.jpg

只有一个reset按钮。

pathletboy 发表于 2013-8-17 11:51:10

海阳 发表于 2013-8-17 11:12 static/image/common/back.gif
只有一个reset按钮。

我找下,上次看到过说可以关闭自动reset的功能。

pathletboy 发表于 2013-8-17 12:05:33

参考下这个http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection

pathletboy 发表于 2013-8-17 12:06:21

reset口上接个上拉电阻,应该就OK。

海阳 发表于 2013-8-17 14:00:52

pathletboy 发表于 2013-8-17 12:06 static/image/common/back.gif
reset口上接个上拉电阻,应该就OK。

感谢!但是我手头没有电阻。
我把读取代码改成read(10)   读前10位,是可以读到的。
readline就不行。

我怀疑,ruby不认arduino的换行符!但是用监视器一读又好了。真是太怪异了。

海阳 发表于 2013-8-17 20:28:32

我找到问题了,是ruby读串口的方式不对。
看了ArduinoFirmata Ruby版的源码。发现根本不用readline。
直接用read 读。好吧。我自己写了一个读line的类。当然还不完善,只是解决了这个问题。

class SerialPortReader

def readline
    sp = SerialPort.open("com4", 9600 , 8,1,SerialPort::NONE) do |sp|
      line =""
      while true   
      c = sp.read(1)   
      line = line + c
      if c=="\n"
          #这里留个位,用块处理line
          yield line

          line = ""
      end
      end
    end
end
end

Randy 发表于 2013-8-18 23:48:10

没看监视看不到是正常的。软件经常挂掉!

hick 发表于 2013-8-19 18:06:33

奇怪,怎么这样.... 跟我用 python 操作的相反,我 python 里头如果打开 monitor, 整个就读不到数据了。

我不大懂串口, 我的实际操作经验是打开都是独占的,我的 python 程序或者 monitor 同时只能有其一操作串口。

海阳 发表于 2013-8-20 13:27:20

hick 发表于 2013-8-19 18:06 static/image/common/back.gif
奇怪,怎么这样.... 跟我用 python 操作的相反,我 python 里头如果打开 monitor, 整个就读不到数据了。

...

对,串口是独占的。
我的问题是,我的自己的程序读不到串口发来的数据。
打开其它监视器,收一下,再关掉它。
再运行自己的程序就能读到了。

不过现在已经解决了。
以前是用readline来读。可能是ruby识别不到串口来的换行符。所以读不到。
我就改成一个字节一字节地读,再自己拼成一个line。这样解决了。

szpapas 发表于 2013-8-23 12:56:19

贡献一下我的代码吧。

require 'serialport'
sp = SerialPort.new "com3", 9600
#sp = SerialPort.new "/dev/tty.PL2303-00002006", 9600
puts "serial opened"

$sxh = 50
def set_k(cmd)
ss="\n\r\00645678901234567890"
$sxh = ($sxh+1) % 128
$sxh = $sxh+1 if $sxh==10 || $sxh == 13
code = cmd.split(' ')
for k in 0..code.size-1
   ss=code.to_i(16)
end
ss = $sxh
for k in 9..19
    ss=0
end
ss = (ss+ss+ss+ss+ss+ss) % 256
ss
end

def hex_str(ss)
str = ''
for k in 0..ss.length-1
    str = str +sprintf("%02X", ss) + ' '
end
str
end

Thread.new {
while true do
    ss = sprintf("%02X ", sp.getc)
    if ss == "0A "
      puts "New Frame:"
      k = 0
    end
    k = k+1
    puts "#{k}: #{ss}"
end
}

#0A 0D 99 34 F2 50 22 01 00 00 00 00 00 00 00 00 00 00 00 00
while (l = gets) do
l = l.chomp
if l == "exit"
    exit
elsif l == "open"
    ss=set_k("F2 50 22 01 00")
    puts("#{Time.now.to_f}:#{hex_str(ss)}")

    sp.write(ss)
elsif l == "close"
    ss=set_k("F2 50 22 00 00")
    puts("#{Time.now.to_f}:#{hex_str(ss)}")

    sp.write(ss)
else
    puts("#{Time.now.to_f}:#{hex_str(l.sub("\n", "\r"))}")
    sp.write(l.sub("\n", "\r"))
end   
end

sp.close
页: [1] 2
查看完整版本: 串口数据读不出!开一下监视器才能读出来,求助!