камни
serialport (1.0.4)
Авторы: Гийом Пьерронне, Алан Стерн, Даниэль Э. Шиптон, Тобин
Ричард, Гектор Парра, Райан С. Пейн
Домашняя страница: http://github.com/hparra/ruby-serialport/
Библиотека для использования последовательных портов RS-232.
рубин
ruby 1.9.3p0 (2011-10-30, редакция 33570) [x86_64-darwin11.2.0]
работает под рвм 1.10.2
Я использую этот драгоценный камень на Mac Lion , и технические характеристики моего устройства следующие.
- 9600
- 7bits
- 1 стоповый бит
- ДАЖЕ паритет
- RTS / CTS используются для контроля отправки / получения
Используемый мной драйвер: md_PL2303_MacOSX10.6_dmg_v1.4.0.zip
http://www.prolific.com.tw/eng/downloads.asp?id=31
После получения данных я должен отправить ACK обратно, чтобы устройство узнало, что данные в порядке.
Вот как у меня сейчас дела.
sp = SerialPort.new("/dev/serial-device", 9600, 7, 1, SerialPort::EVEN)
sp.flow_control = (SerialPort::SOFT | SerialPort::HARD)
loop do
data = sp.gets
p data
while sp.cts() == 0; end #waiting for the device if it's ok to send
sp.putc 0x06.chr #ACK
end
Если устройство не получит ACK в течение 1 секунды после получения данных (data = sp.gets
), оно отправит другие те же данные, чтобы убедиться, что все получилось нормально. В настоящее время я получаю 2-ые те же данные, хотя пытаюсь отправить ACK, как указано выше.
* примечание while sp.cts() == 0; end
не занимает 1 секунду
Если честно, я не уверен, верен ли мой код для отправки ACK. Если кто-нибудь может указать, где я делаю что-то не так, это очень поможет.
Спасибо
обновление
http://ruby -doc.org / ядро-1.9.3 / IO.html # метод-я-putc
putc (obj)
Если obj имеет значение Numeric, напишите символ с кодом
младший байт obj, в противном случае записать первый байт
строковое представление obj в ios. Примечание. Этот метод небезопасен для
используйте с многобайтовыми символами, так как они усекают их.
, поэтому получается, что любой из 4 ниже будет выводить то же самое. Это то, что я нашел до сих пор, но устройство еще не распознает ничего из этого как ACK
и посылает мне вторые те же данные ...
Я думаю, это может быть из-за flow_control
?? (хотя я пробовал SOFT, HARD, NONE, SOFT | HARD)
~ $ irb
1.9.3p0 :001 >
1.9.3p0 :002 > File.open('putc.txt', 'w') do |file|
1.9.3p0 :003 > file.putc 0x06.chr
1.9.3p0 :004?> file.putc 0x06.ord
1.9.3p0 :005?> file.putc 0x06
1.9.3p0 :006?> file.putc 6
1.9.3p0 :007?> end
=> 6
1.9.3p0 :008 >
1.9.3p0 :009 >
1.9.3p0 :010 > data = File.read('putc.txt')
=> "\x06\x06\x06\x06"
1.9.3p0 :011 > data.bytes.to_a
=> [6, 6, 6, 6]
1.9.3p0 :012 >
1.9.3p0 :013 > exit
~ $
~ $ od -a putc.txt
0000000 ack ack ack ack
0000004
~ $
обновление 2
Я попытался использовать tail -f / dev / serial-device, но он не отображался или вышел с ошибкой «занят».
1. используя tty.usbserial для отправки и получения, хвостик tty.usbserial. оба ничего не показали.
2. используя cu.usbserial для отправки и получения, хвост cu.usbserial. Хвост дал мне "занят".
поэтому вместо этого я искал вокруг и нашел команду dtruss, чтобы увидеть, что происходит за сценой.
Process.pid #find this PID
serial_port = SerialPort.new("/dev/tty.usbserial", 9600, 7, 1, SerialPort::EVEN)
serial_port.flow_control = (SerialPort::SOFT | SerialPort::HARD)
loop do
serial_port.gets
while serial_port.cts() == 0; end
p "before putc"
serial_port.putc 0x06.chr
p "after putc"
end
Я запустил это на терминале и открыл другой с помощью sudo dtruss -a -p __PID_FROM_THE_RUBY_CODE__
, и я получил что-то вроде этого
11812/0xfdd0: 5737859 772 11 read(0xB2, "0\0", 0x2000) = 1 0
11812/0xfdd0: 5737866 208 0 sigprocmask(0x1, 0x0, 0x7FFF6FA7B340) = 0x0 0
11812/0xfdd0: 5737869 5 0 sigaltstack(0x0, 0x7FFF6FA7B330, 0x0) = 0 0
...
...
11812/0xfdd0: 5739675 16 11 write(0x1, "\"before putc\"\n\0", 0xE) = 14 0
11812/0xfdd0: 5739685 4 0 sigprocmask(0x1, 0x0, 0x7FFF6FA7B150) = 0x0 0
11812/0xfdd0: 5739686 4 0 sigaltstack(0x0, 0x7FFF6FA7B140, 0x0) = 0 0
11812/0xfdd0: 5739694 9 6 write(0xB2, "\006\0", 0x1) = 1 0
11812/0xfdd0: 5739709 5 0 sigprocmask(0x1, 0x0, 0x7FFF6FA7B1B0) = 0x0 0
11812/0xfdd0: 5739710 3 0 sigaltstack(0x0, 0x7FFF6FA7B1A0, 0x0) = 0 0
11812/0xfdd0: 5739716 8 4 write(0x1, "\"after putc\"\n\0", 0xD) = 13 0
write(0xB2, "\006\0", 0x1)
похоже, что пишет 0x06
. но я вообще не знаю, как это читать ..
истекшее время 5739694 - 5737859 (получение данных gets
- отправка ACK) = 1 835 мксек, я полагаю. так что я думаю, что посылаю ACK до истечения 1 секунды ...
до сих пор нет подсказок, почему я получаю 2-ые данные. (если в противном случае 1 секунда уже прошла, прежде чем я смогу отправить ACK ..?)